Laravel5.1、基本コンポーネントの流れ

タグ: Laravel5  

別の目的でチャートを書いたのですが、ボツにしました。もったいないので公開します。

LaravelのLTSであるバージョン5.1以降で、コンポーネントへ制御が渡る順番を示しています。

ファイル構造に関するLaravelコンポーネント

矢印はコンポーネント単位での処理の順番を表しています。データの流れや依存関係を表したものではありません。ここではフォルダー構造に関連するコンポーネントを主に取り上げています。他にもコンポーネントはたくさん用意されていますが、それらは主に機能を提供しており、アプリケーションの構造に関わるものではありません。言い換えれば、デフォルトのインストール時のファイル構造に関わるコンポーネントの関連を掴んでもらうためのチャートです。

(1)から(13)までがHTTPリクエストを受け取り、処理し、HTTPレスポンスを返すWebアプリケーションとしての基本的な流れを示しています。

(1) サービス利用者が操作を行います。

(2) ブラウザはHTTPリスエストをWebサーバへ送信します。それによりLaraveフレームワークが起動し、リクエストを受け取ります。

(3) フレームワークの起動時にProvider(サービスプロバイダ)が実行されます。サービスプロバイダはコアや業務ロジックの初期起動コードです。

(4) HTTPリクエストはフレームワークにより、Requestインスタンスとしてオブジェクト化されます。

(5) Requestは全リクエストに対し適用されるグローバルミドルウェアによりフィルタリングされます。その後、ルートが定義されているapp/Http/routes.phpが実行されます。

(6) ルート定義に使用するRouteファサードの実体はRouter(ルータ)です。

(7) 各ルート定義はRoute(ルート)としてインスタンス化され、ルータが管理します。

(8)Requestの内容により、 ルーターが起動するコントローラ(とアクションメソッド)を決め、インスタンス化します。続いてRequestはルート毎に指定されたミドルウェアを通過します。次にコントローラへ制御が移り、Requestをコンストラクタ内で指定したミドルウェアへ通過させます。それから、アクションメソッドが実行されます。

(9) ミドルウェアはフィルタリングを担当し、グローバル、ルート指定、コントローラのコンストラクタ指定の三層になっています。コントローラーのアクションメソッド(URIに対応し、ルーターから呼び出されるメソッドのこと)実行以前は、主にRequestの内容を調べ、必要ならばResponseを返しリクエストの処理を中断します。アクションメソッド実行後は主にResponseの内容を必要に応じて変更するために使用します。

(10) コントローラのアクションメソッドは直接Responseを返すか、結果を文字列やJSON、もしくはViewとして返します。Response以外が返されると フレームワークにより、Responseインスタンスが生成されます。返されるResponseはいずれも(9)の説明の通りミドルウェアを通過します。(図上ではミドルウェア通過後になっていますが、実際はコントローラーのアクションメソッドから返された時点でResponsに変換されます。)

(11) Responseインスタンスはテキスト形式のHTTPレスポンスへ変換されます。

(12) HTTPレスポンスはWebサーバを経由し、ブラウザでWebページとして表示されます。

(13) サービス利用者は操作の結果を確認します。

(14)から(26)までは、開発するシステムの業務ロジックに関わる処理の流れです。コントローラに業務ロジックをコードし、処理が複雑になるバッドプラクティスはファット(太った)コントローラと呼ばれます。これを防ぐため、処理は単一の責務を持つ業務ロジックとして実装しましょう。

フォルダー構造に含まれているのはイベントとリスナーのメカニズムと、キューとそれに投入するジョブクラスに関わるファイルです。

(14) コントローラから適切な業務ロジックを呼び出します。

(15) 必要に応じ、別の責務を持つ業務ロジックを呼び出します。

(16) より依存関係を小さくし、独立性と拡張性を高めるため、Event(イベント)を使用することもできます。

(17) Eventが発行されると、それに結び付けられたListener(リスナー)へLaravelにより渡されます。

(18) Listenerは必要な業務ロジックを実行します。(リスナー内に業務コードを書くこともできます。しかし再利用性やテスト、メンテナンス性を考えるのであれば、フレームワークが持っている機構から独立させます。)

(19) 必要であれば、ListenerをQueue(キュー)へ投入し、非同期に実行できます。

(20) 必要であれば、非同期に実行したいロジックをJob(ジョブ)として用意できます。

(21) JobはQueueに投入し非同期に実行します。

(22) 正常系に当てはまらない状況の発生時は、Exception(エクセプション、例外)を発生させます。各Exceptionに対する処理もアプリケーションで定義できます。(app/Exceptions/Handler.php)

(23) HTTPリクエスト以外に、ユーザーによるコマンド入力でも業務ロジックは起動されるでしょう。

(24) コマンドはConsole(コンソール)として実現します。

(25) コントローラに同様に、Consoleに業務ロジックを記述するのは責務の分離という点から好ましくありません。業務ロジックは独立させ、呼び出しましょう。

(26) 必要であれば、コンソールから起動するロジックも、非同期に実行するためJobにできます。

LaravelをMVCだと言ってしまえば、その機能のほとんどを無視することになります。かといって、ドメイン駆動設計やプログラムパターンに精通しなければ、Webアプリができなのであれば、だれもフレームワークを使おうとしなくなるでしょう。LaravelのTaylor Otwellさんがディレクトリー構造として示しているのは、あまりに単純とかなり複雑の「ほど良い」中間地点です。出発地点としてわかりやすく、使いやすいレベルの機能を提供しています。