[Laravel]ミドルウェア(middleware)を使ってみた

Laravel

laravelのmiddlewareで共通処理を実装することがあったので、laravelのmiddlewareについて復習も含めてまとめてみました。
laravel6で確認しています。

公式ページ
公式日本語訳ページ

laravelでのミドルウェア(middleware)とは

ブラウザなどからリクエストを受けて処理する前に何か処理したり、
リクエストの処理が終わった後に何か処理をするようにプログラムを書けるファイルになります。

Qiitaのこちらの記事がイメージ付きでわかりやすいです!

ミドルウェア(middleware)を作る

artisanの下記コマンドで作成することができます。

php artisan make:middleware [ミドルウェア名] 

リクエスト前処理を書く場合

$next()を呼ぶ前に処理を書くと、リクエスト前処理が書けます。

public function handle($request, Closure $next)
{
    // TODO: リクエストが処理される前の処理を書く
    return $next($request);
}

リクエスト後処理を書く場合

$next()を呼んだ後に書くと、リクエスト後処理が書けます。
$next()でコントローラーのロジックを呼んで、responseを取得して返してるようですね。
その間に処理をはさむ…なるほど…

public function handle($request, Closure $next)
{
    $response = $next($request);

    // TODO: リクエストが処理された後の処理を書く

    return $response;
}

ミドルウェアの登録

作ったミドルウェアは登録しないと、動きません。

登録のやり方もいくつかあります。
app/Http/Kernel.phpに作ったミドルウェアを追加します。

今回試したのは2つです。

グローバル登録

HTTPリクエスト全体で動くミドルウェアになります。
app/Http/Kernel.phpの$middleware配列に作ったクラスを追加します。

protected $middleware = [ 
    \App\Http\Middleware\TrustProxies::class,
    \App\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    // TODO: 作ったミドルウェア追加
];

ルート登録

ルーティングで定義しているURLにアクセスした時にだけ動くミドルウェアになります。
ログインしているユーザーだけとか、指定することができます。

ルーティングファイル(web.php)に定義するためにapp/Http/Kernel.phpに連想配列の形式で、$routeMiddleware配列に追加します。

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    // TODO: 作ったミドルウェア追加
];

実際に作ってみる

artisanコマンドでLoggerミドルウェアを作ってみました。

$php artisan make:middleware Logger

ミドルウェアのソース

class Logger
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        \Log::info('[middleware] start run logger');
        $this->outputRequest($request);
        $request = $next($request);
        \Log::info('[middleware] end run logger');

        return $request;
    }

    /**
     * リクエストパラメータ出力.
     * @param Request $request
     */
    private function outputRequest(Request $request)
    {
        $requestMethod = $request->method();
        $requestParams = json_encode($request->all());
        \Log::info("{$requestMethod} : {$requestParams}");
    }
}

中身を上記のように書きました。
受け取ったリクエストをoutputRequestメソッドでログに出力するようにしています。

$request->method()でGETやPOSTなどのメソッド名が取得できて、
$request->all())でパラメータが全部取得できます。(POSTやPUTなどのパラメータも取れます)

ミドルウェア登録

app/Http/Kernel.phpにルート登録しました。

protected $routeMiddleware = [
  // ... 色々省略....
  'logger'           => \App\Http\Middleware\Logger::class,
];

web.phpを修正

2パターン書く方法が有ります。
下記のようにURLに直接書くか、

Route::get('/', function () { return view('welcome'); })->middleware('logger');

routeグループにミドルウェアを定義する方法です。
middlewareの配列は複数並べることが可能です。

Route::group(['middleware' => ['logger']], function () {
    Route::get('/', function () { return view('welcome'); });
});

動作確認

ブラウザにパラメータを付けてアクセスすると…

ログ出力されました!

[2020-06-11 14:43:49] local.INFO: [middleware] start run logger  
[2020-06-11 14:43:49] local.INFO: GET : {"hoge":"abc","test":"898"}  
[2020-06-11 14:43:49] local.INFO: [middleware] end run logger  

ソースはこちら

おわりに

特に難しいことなく、リクエストの後に処理をはさむことができました。

業務ロジックなどを書いているそれぞれのコントローラーに処理を書かずに
簡単に共通処理をかけるのでいいですね!

コメント

タイトルとURLをコピーしました