【Laravel】Pennantでフィーチャーフラグを実装する方法

当ページのリンクには広告が含まれています。
いずみ

こんな悩みを解決できる記事を書きました!

僕は現役フリーランスエンジニア(歴年)で、資格は個保有しています。

Laravel Pennantでフィーチャーフラグを実装したい」とお考えではありませんか?

新機能を一部のユーザーだけに先行公開したり、画面デザインのA/Bテストを回したりする仕組みを、Laravelアプリに入れたい方へ。

Laravel Pennantを使えば、数十行のコードで機能の出し分けを実装できます

いずみ

Laravel公式のパッケージなので導入も簡単です。

ということで、本記事ではLaravel Pennantでフィーチャーフラグを実装する方法を解説します。

いずみ

すぐ読み終わるので、ぜひ最後まで読んでくださいませ。

スクロールできます
【当サイト】おすすめフリーランスエージェント3選
エージェント評価ポイント公式サイト
レバテックフリーランス

5.0
業界最大級のエージェント。
高単価案件が豊富。
公式
Midworks

4.8
満足度調査で
3年連続3冠を達成。
公式
ITプロパートナーズ

4.6
週2〜3向けの案件が豊富。公式
執筆者/監修者
  • フリーランスエンジニア(保有資格個、企業と直接契約
  • ブログ・アフィリエイト歴7年(2018年〜)
  • ブランドせどりで月利50万円⇨脱サラ
  • 投資(仮想通貨・FX)歴7年(2018年〜)
  • X(旧Twitter)フォロワー約1,900人
  • 運営者情報はこちら
いずみです
目次

【Laravel】Pennantでフィーチャーフラグを実装する方法

早速ですが、Laravel Pennantでフィーチャーフラグを実装する手順を見ていきます。

フィーチャーフラグとPennantの概要

フィーチャーフラグは、コードをデプロイしたまま機能のオン・オフを切り替える仕組みです。

新機能を社内メンバーだけに見せる、全体の10%にだけ公開する、問題が出たら即座に止める、といった運用が可能になります。

Laravel Pennantは、フィーチャーフラグをLaravelらしいAPIで扱えるシンプルな公式パッケージです。

判定結果はデフォルトでデータベースに保存され、同じユーザーには同じ結果を返し続けます。

Laravel Pennantのインストール

まずはパッケージを導入します。

STEP
composerでlaravel/pennantを追加する
composer require laravel/pennant
STEP
設定ファイルとマイグレーションを公開する
php artisan vendor:publish --provider="Laravel\Pennant\PennantServiceProvider"

config/pennant.php とマイグレーションファイルが生成されます。

STEP
マイグレーションを実行してテーブルを作成する
php artisan migrate

判定結果を保存する features テーブルが作られます。

いずみ

ここまでで準備は完了です。

クロージャでフィーチャーを定義する

フィーチャーは Feature ファサードの define メソッドで定義します。

サービスプロバイダの boot メソッドに書くのが基本です。

<?php

namespace App\Providers;

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

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Feature::define('new-dashboard', fn (User $user) => match (true) {
            $user->isAdmin() => true,
            $user->created_at->isBefore(now()->subYear()) => true,
            default => Lottery::odds(1, 10),
        });
    }
}

クロージャの戻り値がフィーチャーの初期値になります。

管理者は常に true、1年以上前に登録したユーザーも true、それ以外は10分の1の確率で true という定義です。

Lottery::odds を使うと、ランダムな割合での段階的なロールアウトが手軽に書けます。

いずみ

判定ロジックをクロージャ1つに閉じ込められるのが気持ちいいポイントです。

フィーチャーの状態を判定する

定義したフィーチャーは Feature::active で判定します。

use Laravel\Pennant\Feature;

if (Feature::active('new-dashboard')) {
    // 新しいダッシュボードを表示する
}

// ログインユーザー以外を対象にしたいとき
Feature::for($user)->active('new-dashboard');

// アクティブ時と非アクティブ時で処理を分ける
Feature::when('new-dashboard',
    fn () => $this->newDashboard(),
    fn () => $this->legacyDashboard(),
);

引数を省略すると、ログイン中のユーザーがスコープとして使われます。

Bladeでは @feature ディレクティブが使えます。

@feature('new-dashboard')
    <x-dashboard.new />
@else
    <x-dashboard.legacy />
@endfeature

ルート単位で機能を閉じたいときは、feature ミドルウェアでアクセス自体を制限できます。

use App\Http\Controllers\DashboardController;
use Illuminate\Support\Facades\Route;

Route::get('/dashboard', DashboardController::class)
    ->middleware(['auth', 'feature:new-dashboard']);

フィーチャーが非アクティブなユーザーには400番台のレスポンスが返ります。

いずみ

ミドルウェアで弾けるので、コントローラー側のコードを汚さずに済みます。

クラスベースのフィーチャーで整理する

フラグが増えてきたら、クラスベースのフィーチャーに寄せると管理しやすくなります。

artisanコマンドでクラスを生成します。

php artisan pennant:feature NewDashboard

app/Features/NewDashboard.php が作られるので、resolve メソッドに判定ロジックを書きます。

<?php

namespace App\Features;

use App\Models\User;
use Illuminate\Support\Lottery;

class NewDashboard
{
    public function resolve(User $user): mixed
    {
        return match (true) {
            $user->isAdmin() => true,
            default => Lottery::odds(1, 10),
        };
    }
}

クラスベースのフィーチャーはサービスプロバイダへの登録が不要です。

判定時はフィーチャー名の代わりにクラス名を渡します。

use App\Features\NewDashboard;
use Laravel\Pennant\Feature;

Feature::active(NewDashboard::class);

値付きフィーチャーとキャッシュのクリア

フィーチャーは真偽値だけでなく、文字列や配列などの値も返せます。

use Illuminate\Support\Arr;
use Laravel\Pennant\Feature;

Feature::define('purchase-button', fn () => Arr::random([
    'blue-sapphire', 'seafoam-green', 'tart-orange',
]));

// 真偽値ではなく値そのものを取り出す
$color = Feature::value('purchase-button');

// 一覧表示の前にまとめて解決してクエリ回数を抑える
Feature::for($users)->load(['new-dashboard']);

ボタンの色を3種類でテストする、といったA/Bテストが1つのフィーチャーで書けます。

定義を変更しても、features テーブルに保存済みの結果が優先されて古い値が返ることがあります。

保存済みの結果を消すには pennant:purge コマンドを使います。

php artisan pennant:purge new-dashboard

フィーチャー名を省略すると、保存済みの結果をすべて削除します。

いずみ

定義を直したのに反映されないときは、まず pennant:purge を疑うと早いです。

スクロールできます
【当サイト】おすすめフリーランスエージェント3選
エージェント評価ポイント公式サイト
レバテックフリーランス

5.0
業界最大級のエージェント。
高単価案件が豊富。
公式
Midworks

4.8
満足度調査で
3年連続3冠を達成。
公式
ITプロパートナーズ

4.6
週2〜3向けの案件が豊富。公式

【厳選】フリーランスエンジニアにおすすめなエージェント3選

フリーランスエンジニアになるにはエージェントから案件をもらう必要があります。

僕が実際に利用しているおすすめエージェントを紹介しますね。

いずみ

エージェントは必ず複数登録してください。

担当者によっては「全然案件紹介してくれない…」みたいなこともあるので…

僕は実際に5つのエージェントを使い回していますよ。

フリーランスを始めるなら「

案件数マージン率単価
約88,000件非公開
初心者福利厚生申し込み
無料
Good Point
  • 業界最大級の案件数。
  • 業界トップクラスの高単価報酬、低マージン(平均年収862万円)。
  • 案件参画中のフォローの充実。

※詳細は「【業界最大手】レバテックフリーランスとは?メリットや利用手順を解説!」を参照。

は業界最大手のフリーランスエージェントです。

とにかく案件数が多いので、とりあえず登録しておけば間違いないエージェントです!

いずみ

僕もはじめてフリーランスの案件を貰ったのはです。

保有している案件数が多いので、業務経験がなくても何かしらの案件は紹介してもらえますよ(僕はJavaの経験3年でも案件を貰えました)。

手厚い保障を重視したいなら「

案件数マージン率単価
約10,000件非公開
初心者福利厚生申し込み
無料
Good Point
  • 手厚い保障で正社員並みの安心感。
  • 還元率60%超え&単価公開でクリアな契約。
  • 給与保障制度(審査あり)。

は手厚い保障が特徴のフリーランスエージェントです。

フリーランスを目指しているけど不安な方や保障を重視したい方におすすめです。

いずみ

僕も何度か案件を紹介してもらいました。

自分のスキルに合った案件を紹介してもらえましたし、電話のやり取りも非常に丁寧でした。

週2〜3日の案件探しなら「

案件数マージン率単価
約5,000件非公開
初心者福利厚生申し込み
経験者向け無料
Good Point
  • IT案件に特化したフリーランスエージェント。
  • 週2〜3日の案件が豊富。
  • リモート案件が多く、直エンドなので単価も高い。

※詳細は「【週2・3案件】ITプロパートナーズとは?メリットや利用手順を解説!」を参照。

はIT案件に特化したフリーランスエージェントです。

週2〜3日から参画できる案件が豊富なので、起業したい人にもおすすめです。

いずみ

週2〜3日の案件はある程度スキルがないと紹介してもらえない印象です。

とはいえ、週5の案件ももちろんありますし、僕が利用した時は迅速・丁寧に対応していただきました!

よくある質問

フィーチャーフラグの値はどこに保存されますか?

デフォルトでは database ドライバーが使われ、features テーブルにスコープごとの解決結果が保存されます。

テストや軽い用途では config/pennant.php の default を array に変更すると、メモリ上だけで完結します。

一覧表示でクエリが増えてしまいます。

Feature::for($users)->load([‘new-dashboard’]) のように対象コレクションをまとめて渡してから判定すると、1回のクエリでまとめて解決できます。

Bladeループの中で個別に判定するとN+1クエリになりやすいので注意してください。

テストでフィーチャーを固定したいです。

テストコード内で Feature::define(‘new-dashboard’, true) と再定義すれば、常にアクティブな状態にできます。

Lottery::odds を使った確率的な定義も、Lottery::fix で抽選結果を固定すると判定が安定します。

まとめ

今回は、Laravel Pennantでフィーチャーフラグを実装する方法について解説しました。

以下が本記事のまとめになります。

まとめ
  • Laravel Pennantは composer require laravel/pennant とマイグレーションだけで導入できる。
  • Feature::define でフィーチャーを定義し、Feature::active やBladeの @feature で出し分ける。
  • クラスベースのフィーチャーにすると resolve メソッドに判定ロジックを集約できる。
  • 判定結果は features テーブルにキャッシュされ、pennant:purge でクリアする。
まとめ
  • おすすめ本
¥2,673 (2023/07/23 15:53時点 | Amazon調べ)
\楽天ポイント4倍セール!/
楽天市場

Laravelの勉強なら「」が分かりやすくておすすめですよ♪

いずみ

最後までお読みいただき、ありがとうございました!

スクロールできます
【当サイト】おすすめフリーランスエージェント3選
エージェント評価ポイント公式サイト
レバテックフリーランス

5.0
業界最大級のエージェント。
高単価案件が豊富。
公式
Midworks

4.8
満足度調査で
3年連続3冠を達成。
公式
ITプロパートナーズ

4.6
週2〜3向けの案件が豊富。公式
  • クソおすすめ本
¥4,480 (2024/06/01 23:28時点 | Amazon調べ)
\楽天ポイント4倍セール!/
楽天市場
いずみ

海外のエンジニアがどういった思考で働いているかが理解できます。

海外に行く気はないけど海外エンジニアの動向が気になる雑魚エンジニアにおすすめです(本当におすすめな本しか紹介しないのでご安心を)。

この記事が気に入ったら
フォローしてね!

シェアしてね!
  • URLをコピーしました!
目次