Laravelのルーティングでアノテーションを使う方法

# この記事は？
Laravelのルーティングはweb.phpを使うのが一般的ですが、[LaravelCollective/annotations](https://github.com/laravelcollective/annotations)を使うことでflaskやSpring Bootのようにメソッドにアノテーションをつけてルーティングさせることが可能なので試してみました。
この記事はアノテーションでのルーティングを行うことのメリットとその方法についてまとめます。

# アノテーションでルーティングするメリット
web.phpを使用したルーティングは1ファイルでルーティングを管理することから一覧性があって見やすい反面、複数人で開発を行おうとしたときにweb.phpがコンフリクトする確率が高くなってしまいます。
アノテーションを使用してルーティングを記載するファイルが分かれることで、コンフリクトが減らすことができます。

# アノテーションでルーティングする方法
## 前提
この記事ではLaravelでのプロジェクト作成ができることと何らかの方法でデプロイする方法を持っていることを前提としています。

## Laravelプロジェクトの作成
### Laravelプロジェクトの作成コマンド

```shell
composer create-project laravel/laravel sample_laravel_annotation
```

デプロイしてみてwelcome画面が表示されるか確認してみます。
下記のようにwelcome画面が表示されればプロジェクトの作成には成功しています。
![laravelのインストール確認.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524088/5c82d57f-90d9-8478-5191-53610400166c.png)

## Laravel Collective をインストール
### Laravel Collective をインストールコマンド

```shell
cd sample_laravel_annotation
composer require laravelcollective/annotations
```

## Service Providerの作成
### Service Providerの作成コマンド

```shell
php artisan make:provider AnnotationsServiceProvider
```
上記のコマンドを実行したら`app/Providers/AnnotationsServiceProvider.php`が作成されます。
### Service Providerの編集
作成されたService Providerをもとに下記の通り編集を行います。

```php:app/Providers/AnnotationsServiceProvider.php
<?php

namespace App\Providers;

use Collective\Annotations\AnnotationsServiceProvider as ServiceProvider;

class AnnotationsServiceProvider extends ServiceProvider {

    /**
     * The classes to scan for event annotations.
     *
     * @var array
     */
    protected $scanEvents = [];

    /**
     * The classes to scan for route annotations.
     *
     * @var array
     */
    protected $scanRoutes = [];

    /**
     * The classes to scan for model annotations.
     *
     * @var array
     */
    protected $scanModels = [];

    /**
     * Determines if we will auto-scan in the local environment.
     *
     * @var bool
     */
    protected $scanWhenLocal = true;

    /**
     * Determines whether or not to automatically scan the controllers
     * directory (App\Http\Controllers) for routes
     *
     * @var bool
     */
    protected $scanControllers = true;

    /**
     * Determines whether or not to automatically scan all namespaced
     * classes for event, route, and model annotations.
     *
     * @var bool
     */
    protected $scanEverything = true;

}

```

## Service Providerの登録
追加したService Providerを`config/app.php`内に記載します。

```php:config/app.php
      (中略)
    'providers' => [
      (中略)
      App\Providers\AnnotationsServiceProvider::class,
    ],
      (中略)
```

## Controllerの作成
ここまでで準備は整っているので実際にアノテーションをつけるControllerを作成します。
せっかくなので複数のControllerを作ってルーティングできるようにします。

### 作成コマンド

```shell
php artisan make:controller HogeController
php artisan make:controller FugaController
```

上記を実行すると`app/Http/Controllers/HogeController.php`と`app/Http/Controllers/FugaController.php`が作成されます。

### HogeControllerの編集内容
HogeControllerを下記の通りアノテーションを使って編集します。

```php:app/Http/Controllers/HogeController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HogeController extends Controller
{
  /**
   * @Get("/hoge")
   */
  public function index()
  {
    return 'hoge';
  }
}

```

### FugaControllerの編集内容
FugaControllerを下記の通りアノテーションを使って編集します。

```php:app/Http/Controllers/FugaController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FugaController extends Controller
{
  /**
   * @Get("/fuga")
   */
  public function index()
  {
    return 'fuga';
  }
}

```

これで準備ができたのでそれぞれの画面に遷移してみようと思います。
### /hogeに遷移
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524088/33b0ea69-092a-4f88-4394-4fe3e246b87d.png)

### /fugaに遷移
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524088/c5098033-a8a4-e7d4-ff2a-194bb373f963.png)

無事にアノテーションを使用したルーティングを行うことができました。

# 終わりに
この記事ではアノテーションを使ったルーティングを行うことをメインに話しているのでデメリットには触れていませんでしたが、コメントアウトの部分にアノテーションがあることはこの記法を知らない人からしてみると直感的ではないのでこのことが起因したバグが起きたりするのではないかなとも思いました。
使うか使わないかはプロジェクトメンバーのスキルセットや人数をよく考えた上で決めたほうが良いのだろうなと思います。

今回使用したコードのサンプルは以下に配置します。
https://github.com/KiharaTakahiro/sample_laravel_annotation