Help us understand the problem. What is going on with this article?

Laravel で環境変数を用いて Routing 設定を切り替える

Laravel では環境変数を用いてアプリケーション内の設定を更新することができます。
この記事では Routing 設定を環境変数を用いて切り替える方法について書きます。

動作環境

  • PHP 7.2.26
  • Laravel 6.9.0

TL;DR

  • Controller または Middleware に config() の値を用いた条件分岐を書くことで実現可能。
  • routes/web.php に条件分岐を書くとテストが困難。

シチュエーション

アプリケーションの何らかの機能が廃止され、ある特定のパスへのリクエストを別のパスにリダイレクトさせたいケースについて考えます。
このリダイレクトを行うかどうかは環境変数に応じて決定されるものとします。

// 廃止されるパス
Route::get('/old/resources', 'OldIndexController@index');

// リダイレクト先にしたいパス
Route::get('/new/resources', 'NewIndexController@index')->name('new.resources.index');
config/hoge.php
return [
    // true のとき、 /old/resources から /new/resources へリダイレクトさせる
    'enable_new_resources' => env('ENABLE_NEW_RESOURCES', true),
]

方法1. Controller で条件分岐する

OldIndexController で条件分岐をすると最もシンプルに実現できそうです。

app/Http/Controllers/OldIndexController.php
class OldIndexController
{
    private $redirector

    public function __construct(Redirector $redirector)
    {
        $this->redirector = $redirector;
    }

    public function index()
    {
        if (config('hoge.enable_new_feature')) {
            return $this->redirector->route('new.resources.index', [], 301);
        }

        // 既存の処理
    }
}

方法2: 新規作成した Middleware で条件分岐する

Middleware を使用すれば複数のパスを対象にまとめて設定することもできます。

routes/web.php
Route::middleware(['redirectToNewResources'])->group(function () {
    Route::get('/old/resources', 'OldIndexController@index');
    // 他にリダイレクトさせたいパスがあれば追加する
});
app/Http/Kernel.php
class Kernel extends HttpKernel
{
    protected $routeMiddleware = [
        'redirectToNewResources' => 'RedirectToNewResources::class',
    ]
}
app/Http/Middleware/RedirectToNewResources.php
class RedirectToNewResources
{
    private $redirector

    public function __construct(Redirector $redirector)
    {
        $this->redirector = $redirector;
    }

    public function handle($request, Closure $next)
    {
        if (config('hoge.enable_new_feature')) {
            return $this->redirector->route('new.resources.index', [], 301);
        }

        return $next($request);
    }
}

おまけ: routes/web.php に条件分岐を書く場合(失敗例)

routes/web.php に条件分岐を書いても一応実現できます。

routes/web.php
if (config('hoge.enable_new_feature')) {
    Route::redirect('/old/resources', '/new/resources', 301);
} else {
    Route::get('/old/resources', 'OldIndexController@index');
}

ただしこのように実装した場合、テスト中で Config ファサードを利用して設定を切り替えても Routing には反映されません。
恐らく Laravel 起動時に RouteServiceProvider が読み込まれた時点での Routing 設定が登録されることが原因と思われます。

macloud
M&Aクラウドは「テクノロジーの力で、M&Aに流通革命を」をミッションにM&Aプラットフォーム「M&Aクラウド」を開発運営するスタートアップです。
https://macloud.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away