はむはむエンジニアぶろぐ

365日エンジニアリング

LaravelのルーティングをJavaのSpringフレームワークっぽくした

Laravelは route.php にルーティングを追加していくスタイルですが、JavaのSpringフレームワークのようにアノテーションでルーティングもできます。
以前は、アノテーションもLaravel本体に含まれていたようですが、今は分離されているようです。

LaravelCollectiveのAnnotations を使用することで以下のようなルーティングの記述になります。

<?php

class HogeController
    /**
     * @Get("/{id}", as="index", where={"id": "[0-9]+"})
     */
    public function index(int $id)
    {
        // ...
    }

導入と設定方法をまとめてみました。

はじめに

Laravel Collective Annotationsのドキュメント を参考に進めます。
Laravel本体のバージョンによって若干、導入や設定の手順が異なるので注意。

今回は、 Laravel 5.2 で導入と設定を行いました。

導入方法

Laravel Collective Annotationsをインストール。
Laravel本体のバージョンによってAnnotationsのバージョンも合わせないといけないので注意。

$ composer require "laravelcollective/annotations":"^5.2.1" -vvv

Annotationsサービスプロバイダーの追加・登録

まず、Annotationsサービスプロバイダを追加する必要があります。
Annotationsサービスプロバイダはスキャン対象のクラスを管理します。
スキャン対象にすることで、Laravelから認知されます。
Laravelから認知されることで、アノテーションを用いてルーティングが可能になります。
スキャン対象はコントローラやモデル(広義のクラス), イベントです。

<?php
namespace App\Providers;

use Collective\Annotations\AnnotationsServiceProvider as ServiceProvider;

class AnnotationsServiceProvider extends ServiceProvider {

    /**
     * スキャン対象のイベント
     * 追加後、スキャンコマンドを走らせること
     *
     * php artisan event:scan
     *
     * @var array
     */
    protected $scanEvents = [
        \App\SampleEvent::class,
    ];

    /**
     * スキャン対象のコントローラ
     * $scanControllersをtrueに設定しているので、明示的なパス指定は不要
     * 追加後、スキャンコマンドを走らせること
     *
     * php artisan route:scan
     *
     * @var array
     */
    protected $scanRoutes = [];

    /**
     * スキャン対象のモデル
     * 追加後、スキャンコマンドを走らせること
     *
     * php artisan model:scan
     *
     * @var array
     */
    protected $scanModels = [];

    /**
     * local環境の場合にtrueを指定していると自動的にスキャンされる
     *
     * @var bool
     */
    protected $scanWhenLocal = false;

    /**
     * trueに設定しているとApp\Http\Controllers配下を自動的にスキャンする
     *
     * @var bool
     */
    protected $scanControllers = true;

    /**
     * trueに設定していると全てのnamespaceからイベントもコントローラもモデルも自動スキャンする
     * クラスの数が多いとスキャンに時間がかかってしまう
     *
     * @var bool
     */
    protected $scanEverything = false;
}


Annotationsサービスプロバイダを作成しただけでは有効になりません。
config/app.phpにAnnotationsサービスプロバイダを登録します。

<?php
    // ...
    "providers" => [
    // ...
      App\Providers\AnnotationsServiceProvider::class,

イベントの追加・登録

Annotationsサービスプロバイダにイベントを登録しておくと、コントローラからイベントを呼び出すことができます。
まず、イベントを追加します。

<?php

namespace App;

class SampleEvent {

    /**
     * @Hears("hoge")
     */
    public function hoge(int $id)
    {
        echo "id=" . $id;
    }
}


追加したイベントは、Annotationsサービスプロバイダに登録をします。

<?php
namespace App\Providers;

use Collective\Annotations\AnnotationsServiceProvider as ServiceProvider;

class AnnotationsServiceProvider extends ServiceProvider {

    /**
     * スキャン対象のイベント
     * 追加後、スキャンコマンドを走らせること
     *
     * php artisan event:scan
     *
     * @var array
     */
    protected $scanEvents = [
        \App\SampleEvent::class,
    ];

コントローラの追加・登録

コントローラを作成し、アノテーションを付与します。
また、fireメソッドでイベントを呼び出しています。

<?php

namespace App\Http\Controllers;
/**
 * @Controller(prefix="test")
 */
class TestController extends Controller
{
    /**
     * @Get("/{id}", as="index", where={"id": "[0-9]+"})
     */
    public function index(int $id, \Illuminate\Contracts\Events\Dispatcher $d)
    {
      // イベントの呼び出し
      $d->fire('hoge', $id);
    }


コントローラの登録は、AnnotationsServiceProviderの scanRoutes に追加するか scanControllers をtrueにします。
私はscanControllersをtrueにして作っています。

動作確認

以下のコマンドを実行する必要があります。
スキャン対象のクラスが増える度に忘れずにスキャンします。

$ php artisan route:scan
$ php artisan event:scan

以上の設定を行うことで、アクセスが可能になりました。
http://サーバのIPアドレス/test/1
イベントを設定したので、 id=1 がechoされます。