ユアマイスター株式会社エンジニアブログ

ユアマイスター株式会社のエンジニアが日々徒然。

CakePHP3 の Middleware 導入編

f:id:yourmystar_engineer:20191201135702p:plain


この記事はユアマイスター Advent Calendar 20194日目の記事です。 (愉快なユアマイスターの仲間たちが書いている他の記事もぜひご覧くださいませ。)


どうも。ユアマイスター星(@inase17000)です。

さて、ユアマイスターではWebサービスをCakePHP3系で開発しています。

yourmystar-engineer.hatenablog.jp ※その他の開発環境も前に書いたのでご覧ください。

CakePHP3に含まれているMiddlewareをご存知でしょうか?

仕組みを理解して自分たちのオリジナルの処理を追加すると、とても便利に使い倒すことができます。今回ユアマイスターでも導入と自作Middlewareを追加する機会がありましたので、後学のために記録に残しておこうと思います。

環境

記事を書いている時点の手元の環境は以下の通り。(PHP7.4が出たから試してみたいなあぁ...)

CakePHP3 の Middleware

早速、オフィシャルドキュメントCookbookを見てみると、

https://book.cakephp.org/3/ja/controllers/middleware.html

- ミドルウェアクラスのファイルは src/Middleware に置かれるべきです。例えば src/Middleware/CorsMiddleware.php です。
- ミドルウェアクラスには Middleware と接尾語が付けられるべきです。例えば LinkMiddleware です。
- ミドルウェアはミドルウェアのプロトコルを実装することを期待されています。

とゆるい制約事項が設けられているようです。

さて、ここに出てくる「ミドルウェア」という言葉ですが、一般的には ApacheTomcatのようなアプリケーションを動かすために必要なもので、OSとの橋渡しを行ってくれるものを指した呼称として使用することがほとんどです。定義が曖昧な分「ミドルウェア」に該当するものは、数えだしたらキリがありません。

CakePHP3の「ミドルウェア」に関して実際に利用してみると、これらの「ミドルウェア」とは少し違うイメージを持つと思います。言葉は一緒だけど全然別物です。

CakePHP3の「ミドルウェア」はPSR-7で定義されたリクエストやレスポンスのハンドリング、玉ねぎ状の連鎖的な処理など特徴的な側面を持っています。

PSR-7ってなに?

https://www.php-fig.org/psr/psr-7/

PHPのWebアプリケーションにおけるHTTPリクエスト( Psr\Http\Message\RequestInterface )/レスポンス( Psr\Http\Message\ResponseInterface )を含む、HTTPメッセージオブジェクトの取り扱いに関する標準定義です。他にも細かいルールはたくさんあるのですが、説明は上記リンク先に任せます。

PSR-7準拠の何が嬉しいかというと、他のフレームワークやライブラリーでPSR-7互換で作られたものを簡単に利用できるということです。自分で作ったミドルウェアもPSR-7準拠しておけば、世界中の人にcomposer経由で使ってもらうことが可能です。夢が広がりますね。

玉ねぎ状の連鎖的な処理ってなに?

f:id:yourmystar_engineer:20191201145022j:plain

上から順にリクエストがMiddlewareを通って、アプリケーションを通り、またMiddlewareを通ってレスポンスを返す流れを示しています。

①Aミドルウェアの前処理を行い、次のミドルウェアを呼び出す

②Bミドルウェアの前処理を行い、次のミドルウェアを呼び出す

③Cミドルウェアの前処理を行い、アプリケーションの処理を呼び出す

④コントローラーの処理を行い、Cミドルウェアを呼び出す

⑤Cミドルウェアの後処理を行い、次のミドルウェアを呼び出す

⑥Bミドルウェアの後処理を行い、次のミドルウェアを呼び出す

⑦Cミドルウェアの後処理を行い、レスポンスを返却する

この仕組みにより、互いのミドルウェアは疎になり、リクエストオブジェクト・レスポンスオブジェクトの更新を行うことが役割の処理に集中することができるわけです。

CakePHPのバージョンアップとともにMiddlewareを導入する

過去のバージョンからCakePHPを使っていて、プロジェクトの中に、 Application.php がない場合、Middlewareの導入のために Application.php 自体を準備する必要があります。(最新バージョンのCakePHP3にはスケルトン状態から Application.php が含まれていますのでこの手順は不要です)

https://book.cakephp.org/3/ja/development/application.html#adding-http-stack

  1. webroot/index.php の更新(参照:app/index.php at master · cakephp/app · GitHub
  2. Application.php の作成(参照:app/Application.php at master · cakephp/app · GitHub
  3. config/requirements.php の作成 (参照:app/requirements.php at master · cakephp/app · GitHub

基本的には、超簡単にフレームワークの用意したレールに乗るだけで自動的に使い始めることができるのです。

どんな使い道があるのか?

既存で様々なMiddlewareが同梱されています。

https://book.cakephp.org/3/ja/controllers/middleware.html#cakephp https://api.cakephp.org/3.6/namespace-Cake.Http.Middleware.html

Packagistを見ても、PSR-7準拠のmiddlewareはわんさか。

https://packagist.org/search/?query=psr-7%20middleware&tags=psr-7

互いの処理を疎にできるルールになっているから、小さなタスクをMiddlewareに切り出しやすくなっているんでしょうね。設計大事。

ユアマイスターでの導入

ユアマイスターでは、「あなたのマイスター」のアプリケーションに

  • ErrorHandlerMiddleware
  • AssetMiddleware
  • RoutingMiddleware
  • CsrfProtectionMiddleware

の4つを有効にして導入しました。CsrfProtectionMiddlewareに関しては、Formヘルパーを使わずに <form> タグを直書きしてるところが残存しておりエラーが出るというちょっとしたトラブルは発生しましたが、ほとんど手間なく導入完了にまで持ってこれました。

以上、簡単ではありますが、Middleware導入にあたり必要になりそうな知識をおとどけました。 次回は、オリジナルMiddlewareを作成予定でその工程と結果をお伝えできればと思います!!!!!!

さー開発合宿だ!

ユアマイスター では一緒にはたらくエンジニアを募集しています。

▼お気軽にご連絡ください▼

https://corp.yourmystar.jp/recruit

お気軽にご連絡お待ちしてます!!