はじめに
こんばんは。最近ちょっとずつcakephp3を触っている僕です。
まだよちよちですが、なんとなく触ってこんな感じかと確かめてます。
で、今回は、laravelみたいにrouteファイルを分けられないかなと挑戦してみました。
cakephp3は基本的にconfigフォルダ直下にroutes.phpがあり、そこで一括管理しているみたいです。
laravelみたいにデフォでrouteファイルが分かれている方が、「僕的には」スッキリしていいかなと感じたので、できるかどうかちょっとやってみました。
※あくまでルーティングファイルをわけるだけの作業です。
やってみた
cakephp3のroute管理は、RoutingMiddleware
としてMiddleware登録されているみたいです。
デフォルトでApplication.phpに記載されていると思います。
<?php ... $middlewareQueue->add(new RoutingMiddleware($this));
そして、Applicationクラスが継承している BaseApplicationクラス
にroute判定する際に実行されるメソッドが存在します。
<?php ... /** * {@inheritDoc} * * By default this will load `config/routes.php` for ease of use and backwards compatibility. * * @param \Cake\Routing\RouteBuilder $routes A route builder to add routes into. * @return void */ public function routes($routes) { if (!Router::$initialized) { // Prevent routes from being loaded again Router::$initialized = true; require $this->configDir . '/routes.php'; } }
この、routes()は、Middlewareとして登録されたRoutingMiddlewareの __invoke() メソッド内で呼び出されるloadRoutes()
によって実行されています。
というわけで、routesメソッドをまるっとオーバライドして、以下みたいに変えます。
<?php .... public function routes($routes) { if (!Router::$initialized) { require $this->configDir . '/routes.php'; require $this->configDir . '/routes_api.php'; // Prevent routes from being loaded again Router::$initialized = true; } }
requireしている箇所に一個足しているだけですね。
次にrequireしているroutes_api.phpを作成します。
<?php use Cake\Routing\RouteBuilder; use Cake\Routing\Router; use Cake\Routing\Route\DashedRoute; Router::defaultRouteClass(DashedRoute::class); Router::prefix('api', function (RouteBuilder $routes) { $routes->get('/test', ['controller' => 'test', 'action' => 'index']); });
prefixを指定することでnamespaceも App/Controller/Api
にすることが出来ます。
最後にroutingで設定しているコントローラを作成します。
<?php namespace App\Controller\Api; use App\Controller\AppController; class TestController extends AppController { public function index() { return $this->response->withType('application/json')->withStringBody(json_encode([ 'controller' => 'test', 'action' => 'index', 'prefix' => 'api', 'url' => '/api/test', 'result' => 1 ])); } }
出来ました。
終わりに
とまぁちょっと思いついたんでここまでやってみました。
実運用で使うかは微妙ですが。。
plugin機能使えばいいわけだし。
ただpluginはディレクトリツリーが深くなっちゃうので、そこがネックかなーと。
なんか他に方法あれば教えてください。
ではでは。