Skip to main content

パイプラインパターンとは

パイプラインパターンは、処理対象のオブジェクト(passable)を一連のパイプ(処理ステップ)に順番に通すデザインパターンです。各パイプは前のステップの出力を受け取り、処理を加えて次のステップに渡します。 Laravelでは Illuminate\Pipeline\Pipeline クラスがこのパターンを実装しており、ミドルウェアの処理がまさにこの仕組みで動いています。

Laravelコアでの使用箇所

パイプラインはLaravelの中核で広く使われています。
  • HTTPミドルウェアIlluminate\Foundation\Http\Kernel でリクエストをミドルウェアのパイプラインに通す
  • コンソールコマンド — Artisanコマンドの前後処理
  • Routerのミドルウェア — ルートグループのミドルウェア適用
HTTPカーネルがパイプラインを使う部分を見てみましょう。

基本的な使い方

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 に渡すことで、呼び出し順を正しく保ちます。最初のパイプが最初に実行されるよう、クロージャのスタックを内側から積み上げていきます。
パイプラインは「タマネギ型」アーキテクチャとも呼ばれます。リクエストは外側の層(最初のパイプ)から内側に向かって通過し、レスポンスは内側から外側に戻ってきます。各ミドルウェアが $next() を呼ぶ前後に処理を加えられるのはこのためです。

Macroableトレイトの併用

Pipeline クラスは Macroable トレイトを使っているため、独自のメソッドを追加できます。

次のステップ

Macroableトレイト

既存クラスに独自メソッドを追加するMacroableトレイトの使い方を学びます。
最終更新日 2026年3月27日