Laravel10の新機能 Pennantを試す

こんにちは、コバヤシです。
今回はlaravel10から実装されたPennantの機能を試してみたいと思います。

Pennant機能とは

Pennant機能とは、Laravel 10で新たに導入された、アプリケーションのフラグ管理を助けるツールです。この機能を使うと、アプリケーションの特定の部分を有効化したり無効化したりするフラグを設定できます。例えば、管理者だけに特定の機能を表示したい場合、Pennantを使ってフラグを設定することで、その制御が簡単に行えます。

laravel.com

readouble.com

では、早速Pennantを使ってみましょう。

インストール

Pennantはデフォルトでは入っていないので、Composerでインストールを行います。

composer require laravel/pennant

次に、"vendor:publish"というArtisanコマンドを使って、Pennantの設定とデータベースの変更を管理するためのマイグレーションファイルをプロジェクトに公開(コピー)します。 これによりconfigにpennant.phpとdatabase/migrationsにcreate_features_table.phpが作成されます。

php artisan vendor:publish --provider="Laravel\Pennant\PennantServiceProvider"

最後に、マイグレーションを実行します。

php artisan migrate

featuresテーブルが作成されました。

Feature::defineを使ってフィーチャーフラグを設定する

次にAppServiceProviderにFeature::defineを記述します。 Feature::defineはフィーチャーフラグ(判定処理)を定義するためのメソッドとになります。

app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\AppService;
use App\Models\User;
use Laravel\Pennant\Feature;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        // isAdminの項目が1の時にtrueを返す
        Feature::define('admin', fn(User $user) => match (true) {
            (bool) $user->is_admin => true,
            default => false,
        });
    }
}

フラグの判定を行う

Feature::defineで設定したフラグの判定を行うには、以下のようにします。

<?php
if (Feature::active('admin')) {
    // 管理者の時の何らかの処理
}

管理者では無い判定の場合は

<?php
if (Feature::inactive('admin')) {
    // 管理者で無い時の何らかの処理
}

とします。

その他の判定方法として
・allAreActive
・someAreActive
・allAreInactive
・someAreInactive

なども用意されています。

表示の切り替えを行う

viewで表示の切り替えを行うには、bladeの@featureディレクティブを使用します。

@feature('admin')
<p>管理者です</p>
@endfeature

@elseなどの分岐も使えます。

判定のキャッシュ

Pennantでは判定された結果はデータベースに保存されます。これはリクエストの間、一貫した結果を持つことを保証するためです。
これはABテストなどの表示切替では有効なのですが、ユーザーの権限の切り替えでは問題が発生します。
権限の設定を切り替えても表示が変わらないという事です。

これを解決するためのコマンドが用意されています。

<?php
// 現在ログインしているユーザーの権限をアクティブに変更
Feature::activate('admin');

// 現在ログインしているユーザーの権限を無効に変更
Feature::deactivate('admin');

// 指定したユーザーの権限をアクティブに変更
Feature::for($user)->deactivate('admin');

上記の方法では、
実際にDBに保存されている設定値とは別に設定されるので注意が必要です。 (ユーザーテーブルではis_adminが0なのに表示できるということ)

いっそのこと以下のようにキャッシュを消して改めてDBの設定からキャッシュを作成させる方が良いかもしれません。

<?php
// ログイン中のユーザーのadminフラグのキャッシュを削除する
Feature::forget('admin');

まとめ

いかがだったでしょうか。 今回は、権限による表示や処理の切り替え、ABテストなどが簡単に実装できることをご紹介しました。
キャッシュ周りには注意が必要ですが、自分で一から実装するよりも簡潔に記述できるのが魅力です。 他にも色々機能はあるので、気になる方はリファレンスを確認してみてください。