Posted at

Laravelのルーティングをアノテーションで指定する

More than 1 year has passed since last update.

Laravelのルーティングは、設定ファイル(routes.php)に記述するのが標準のやり方である。だが、私は個人的にルーティングに関しては「設定より規約」でやりたい質である。そこで、わざわざ設定ファイルを見に行く、或いは作るという事をやらずに済むような方法を探す事となった。


Laravel Collective

理想としているのは、何もしなくてもコントローラー名とアクション名からデフォルトのルーティングを組み立ててくれるというものなのだが、それを実現できるような既存の仕組みは見当たらなかった。

しかし、Laravel Collectiveを利用すれば、コントローラー上にアノテーションを記述する事でルーティングを指定できるというので、これを利用してみた。インストールするのは、Laravel Collectiveの中でもアノテーション記法を利用するためのパッケージである。

なお、Laravel CollectiveはLaravelコアから取り除かれたコンポーネントをメンテナンスしているプロジェクトである。利用する際にはその点を念頭に置いておきたい。


インストール

まずは以下のComposerパッケージをインストールする。

composer require "laravelcollective/annotations":"^5.3.0"

次に、サービスプロバイダークラスを追加する。

設定内容については後述するので、まずはそのまま貼り付けておこう。


app/Providers/AnnotationsServiceProvider.php

<?php

namespace App\Providers;

use Collective\Annotations\AnnotationsServiceProvider as ServiceProvider;

class AnnotationsServiceProvider extends ServiceProvider {

/**
* イベントのアノテーションをスキャンするクラス
*
* @var array
*/

protected $scanEvents = [];

/**
* ルーティングのアノテーションをスキャンするクラス
*
* @var array
*/

protected $scanRoutes = [];

/**
* モデルのアノテーションをスキャンするクラス
*
* @var array
*/

protected $scanModels = [];

/**
* local環境の場合に自動的にスキャンするか
*
* ドキュメントではfalseだが、私はtrueにしている。
*
* @var bool
*/

protected $scanWhenLocal = true;

/**
* コントローラーのディレクトリー (Serend\Http\Controllers) から、
* ルーティングのアノテーションを自動的にスキャンするか
*
* 注意:スキャン対象はControllers直下のみとなる。再帰的ではない。
*
* @var bool
*/

protected $scanControllers = false;

/**
* 名前空間内の全てのクラスから、
* イベント・ルーティング・モデルのアノテーションを自動的にスキャンするか
*
* 注意:アプリケーションのサイズに応じて、スキャン時間が長くなる。
*
* @var bool
*/

protected $scanEverything = false;

}


最後にお約束通り、サービスプロバイダーを有効にする。


config/app.php

    'providers' => [

// ...
App\Providers\AnnotationsServiceProvider::class
// ...
];


サービスプロバイダーの設定とスキャンについて

サービスプロバイダーの設定で、「スキャン」という言葉が何箇所か出ている。これは何かというと、記述したアノテーションを読み込んで有効化する事である。ルーティングのアノテーションをスキャンする方法は幾つかあるが、先述の通り設定した場合は、次の通りとなる。


  • local環境の場合、常に自動的にスキャンされる。

  • local環境以外の場合、php artisan route:scanコマンドを実行する。

他にはprotected $scanRoutesにスキャン対象のコントローラークラスを指定する事もできるが、先の設定にしておけばデプロイ時に毎回artisanコマンドを実行する事で全てのコントローラークラスをスキャンしてくれるので、そちらをお薦めする。


アノテーションの記述方法


@Resource

まずはAPI等を実装する際に役立つ@Resourceについて。

/**

* @Resource('users')
*/

class UserController extends Controller {
}

これは、以下と同義である。

Route::resource('users', 'UserController');

アクションを絞りたい場合は、@Resources('users',only={"index","show"})のように記述すれば良い。


@Get


```php
/**
* @Get("users/login")
*/
public function login(Request $request)
{
}

これは、以下と同義である。

Route::get('users/login', [

'as' => 'users.login', 'uses' => 'UserController@login'
]);


@Post, @Put, @Delete, etc...

Get以外のHTTPリクエストについても、同様の記法が利用できる。


まとめ

Laravel Collectiveのアノテーションパッケージを使えば、ルーティングをコントローラー上にアノテーションで記述できる。「設定より規約」的な考え方で、原則としてコントローラー名とアクション名から規則的なルーティングを行っている場合などは特に、扱うファイルが減る分だけ効率的に開発できるだろう。

なお、Laravel Collectiveにはこれ以外にも様々なパッケージがあるし、アノテーションパッケージの中にも紹介し切れていないものがある(実際、私は@Middleware等も利用している)。それらについては公式ドキュメントが充実しているので、適宜参照して頂くと良いだろう。