パイプラインパターンとは
パイプラインパターンは、処理対象のオブジェクト(passable)を一連のパイプ(処理ステップ)に順番に通すデザインパターンです。各パイプは前のステップの出力を受け取り、処理を加えて次のステップに渡します。 LaravelではIlluminate\Pipeline\Pipeline クラスがこのパターンを実装しており、ミドルウェアの処理がまさにこの仕組みで動いています。
Laravelコアでの使用箇所
パイプラインはLaravelの中核で広く使われています。- HTTPミドルウェア —
Illuminate\Foundation\Http\Kernelでリクエストをミドルウェアのパイプラインに通す - コンソールコマンド — Artisanコマンドの前後処理
- Routerのミドルウェア — ルートグループのミドルウェア適用
基本的な使い方
send / through / thenReturn
最もシンプルなパイプラインの構成です。send($passable)— パイプラインに通すオブジェクトを指定するthrough($pipes)— パイプの配列を指定するthenReturn()— パイプラインを実行して結果を返す
then
最終的な処理をクロージャで指定したい場合はthen() を使います。
pipe
後からパイプを追加するにはpipe() を使います。
クラスベースのパイプ
クロージャの代わりに専用クラスを使うことで、再利用性が高まります。各パイプクラスはhandle メソッドを実装します。
via — 呼び出すメソッドを変更する
デフォルトではパイプのhandle メソッドが呼ばれますが、via() で別のメソッド名を指定できます。
パイプへのパラメーター渡し
クラス名に: と , を使ってパイプにパラメーターを渡せます。これはミドルウェアの throttle:60,1 のような構文と同じ仕組みです。
finally — パイプライン終了後の処理
finally() メソッドを使うと、パイプライン終了後に必ず実行されるコールバックを登録できます。成功・失敗に関わらず実行されます。
withinTransaction — トランザクション内での実行
Laravel 11以降、パイプライン全体をデータベーストランザクション内で実行できます。実践例:注文処理パイプライン
ECサイトの注文処理を複数のパイプで構成する例です。1
パイプクラスを作成する
2
パイプラインを実行する
Pipeline の内部実装
carry() メソッドがパイプラインの核心部分です。array_reduce を使ってパイプを右から左に畳み込み、クロージャのチェーンを構築します。
array_reverse でパイプを逆順にして array_reduce に渡すことで、呼び出し順を正しく保ちます。最初のパイプが最初に実行されるよう、クロージャのスタックを内側から積み上げていきます。
Macroableトレイトの併用
Pipeline クラスは Macroable トレイトを使っているため、独自のメソッドを追加できます。
次のステップ
Macroableトレイト
既存クラスに独自メソッドを追加するMacroableトレイトの使い方を学びます。