Laravelのrouteを理解して、正しいルーティングを書く（group・prefix ・middleware・ namespace・ as）

こんにちは、JeffTechです。

# 説明
ルーティングする時に何かと出てくる`group`や`prefix`、`middleware`、`namespace`、`as`について説明していきます。





# この記事で実現できること
- routes/web.phpやroutes/api.phpに書いてあることが理解できるようになる





# 開発環境
- OS:MacOS Catalina
- PHP:7.3
- Laravel:6.2





# 実装




## 今回使用する例

```php:routes/web.php
<?php

Route::get('post/index', 'PostController@index')->name('posts.index');
Route::get('post/create', 'PostController@create')->name('posts.create');
Route::post('post/store', 'PostController@store')->name('posts.store');
Route::get('post/show/{post}', 'PostController@show')->name('posts.show');
Route::get('post/edit/{post}', 'PostController@edit')->name('posts.edit');
Route::post('post/update/{post}', 'PostController@update')->name('posts.update');
Route::post('post/destroy/{post}', 'PostController@destroy')->name('posts.destroy');

Route::get('user/index', 'Admin\UserController@index')->name('users.index');
Route::get('user/create', 'Admin\UserController@create')->name('users.create');
Route::post('user/store', 'Admin\UserController@store')->name('users.store');
Route::get('user/show/{user}', 'Admin\UserController@show')->name('users.show');
Route::get('user/edit/{user}', 'Admin\UserController@edit')->name('users.edit');
Route::post('user/update/{user}', 'Admin\UserController@update')->name('users.update');
Route::post('user/destroy/{user}', 'Admin\UserController@destroy')->name('users.destroy');
```
上記のようなルーティングがされている時を例にして、説明していきます。




## groupとprefixについて
`group`は、ある規則性を持ったルーティングを一つのまとまりにするために使います。
`prefix`は、URIのプレフィックスを設定することができます。
今回の例を使用するとこんな感じになります。

```php:routes/web.php
<?php

Route::group(['prefix' => 'post'], function () {
    Route::get('index', 'PostController@index')->name('posts.index');
    Route::get('create', 'PostController@create')->name('posts.create');
    Route::post('store', 'PostController@store')->name('posts.store');
    Route::get('show/{post}', 'PostController@show')->name('posts.show');
    Route::get('edit/{post}', 'PostController@edit')->name('posts.edit');
    Route::post('update/{post}', 'PostController@update')->name('posts.update');
    Route::post('destroy/{post}', 'PostController@destroy')->name('posts.destroy');
});


Route::group(['prefix' => 'user'], function () {
    Route::get('index', 'Admin\UserController@index')->name('users.index');
    Route::get('create', 'Admin\UserController@create')->name('users.create');
    Route::post('store', 'Admin\UserController@store')->name('users.store');
    Route::get('show/{user}', 'Admin\UserController@show')->name('users.show');
    Route::get('edit/{user}', 'Admin\UserController@edit')->name('users.edit');
    Route::post('update/{user}', 'Admin\UserController@update')->name('users.update');
    Route::post('destroy/{user}', 'Admin\UserController@destroy')->name('users.destroy');
});
```
`group`と`prefix`を使う前と後のルーティングを`$ php artisan route:list`を使って見比べてみてください。
全く違いがないと思います。




## asについて
`as`は、`$ php artisan route:list`したときのNameにプレフィックスを設定することができます。
今回の例を使用するとこんな感じになります。

```php:routes/web.php
<?php

Route::group(['as' => 'posts.'], function () {
    Route::get('post/index', 'PostController@index')->name('index');
    Route::get('post/create', 'PostController@create')->name('create');
    Route::post('post/store', 'PostController@store')->name('store');
    Route::get('post/show/{post}', 'PostController@show')->name('show');
    Route::get('post/edit/{post}', 'PostController@edit')->name('edit');
    Route::post('post/update/{post}', 'PostController@update')->name('update');
    Route::post('post/destroy/{post}', 'PostController@destroy')->name('destroy');
});

Route::group(['as' => 'users.'], function () {
    Route::get('user/index', 'Admin\UserController@index')->name('index');
    Route::get('user/create', 'Admin\UserController@create')->name('create');
    Route::post('user/store', 'Admin\UserController@store')->name('store');
    Route::get('user/show/{user}', 'Admin\UserController@show')->name('show');
    Route::get('user/edit/{user}', 'Admin\UserController@edit')->name('edit');
    Route::post('user/update/{user}', 'Admin\UserController@update')->name('update');
    Route::post('user/destroy/{user}', 'Admin\UserController@destroy')->name('destroy');
});
```
`as`を使う前と後のルーティングを`$ php artisan route:list`を使って見比べてみてください。
全く違いがないと思います。





## namespaceについて
`namespace`は、コントローラのパスを共通化することができます。

```php:routes/web.php
<?php

Route::get('post/index', 'PostController@index')->name('posts.index');
Route::get('post/create', 'PostController@create')->name('posts.create');
Route::post('post/store', 'PostController@store')->name('posts.store');
Route::get('post/show/{post}', 'PostController@show')->name('posts.show');
Route::get('post/edit/{post}', 'PostController@edit')->name('posts.edit');
Route::post('post/update/{post}', 'PostController@update')->name('posts.update');
Route::post('post/destroy/{post}', 'PostController@destroy')->name('posts.destroy');

Route::group(['namespace' => 'Admin'], function () {
    Route::get('user/index', 'UserController@index')->name('users.index');
    Route::get('user/create', 'UserController@create')->name('users.create');
    Route::post('user/store', 'UserController@store')->name('users.store');
    Route::get('user/show/{user}', 'UserController@show')->name('users.show');
    Route::get('user/edit/{user}', 'UserController@edit')->name('users.edit');
    Route::post('user/update/{user}', 'UserController@update')->name('users.update');
    Route::post('user/destroy/{user}', 'UserController@destroy')->name('users.destroy');
});
```
`PostController`は、`app/Http/Controllers`配下にあるため、namespaceの設定は特にいりません。
`UserController`は、`app/Http/Controllers/Admin`配下にあるため、`Admin`部分をnamespaceで上記のように設定することができます。
`namespace`を使う前と後のルーティングを`$ php artisan route:list`を使って見比べてみてください。
全く違いがないと思います。





## middlewareについて
`middleware`は、各routeにmiddlewareを割り当てることができます。
middlewareの説明は省きますが、ログインしているかの判定をしてくれる`authミドルウェア`を今回は例として設定していきます。

```php:routes/web.php
<?php

Route::get('post/index', 'PostController@index')->name('posts.index');
Route::get('post/show/{post}', 'PostController@show')->name('posts.show');
Route::group(['middleware' => 'auth'], function () {
    Route::get('post/create', 'PostController@create')->name('posts.create');
    Route::post('post/store', 'PostController@store')->name('posts.store');
    Route::get('post/edit/{post}', 'PostController@edit')->name('posts.edit');
    Route::post('post/update/{post}', 'PostController@update')->name('posts.update');
    Route::post('post/destroy/{post}', 'PostController@destroy')->name('posts.destroy');

    Route::get('user/index', 'Admin\UserController@index')->name('users.index');
    Route::get('user/create', 'Admin\UserController@create')->name('users.create');
    Route::post('user/store', 'Admin\UserController@store')->name('users.store');
    Route::get('user/show/{user}', 'Admin\UserController@show')->name('users.show');
    Route::get('user/edit/{user}', 'Admin\UserController@edit')->name('users.edit');
    Route::post('user/update/{user}', 'Admin\UserController@update')->name('users.update');
    Route::post('user/destroy/{user}', 'Admin\UserController@destroy')->name('users.destroy');
});
```
`$ php artisan route:list`を行うと、middlewareのところに、`posts.index`と`posts.show`以外に`auth`と付いてるのがわかると思います。
つまり、このようにルーティングすると、postの一覧画面(posts.index)とpostの詳細画面(posts.show)以外のページを見るためには、ログインが必要になります。




## 全部をまとめて書いてみた
`group`、`prefix`、`as`、`namespace`、`middleware`の全部盛りをするとこんな感じになります。

```php:routes/web.php
<?php

Route::group(['prefix' => 'post', 'as' => 'posts'], function () {
    Route::get('index', 'PostController@index')->name('index');
    Route::get('show/{post}', 'PostController@show')->name('show');
});

Route::group(['middleware' => 'auth'], function () {
    Route::group(['prefix' => 'post', 'as' => 'posts.'], function () {
        Route::get('create', 'PostController@create')->name('create');
        Route::post('store', 'PostController@store')->name('store');
        Route::get('edit/{post}', 'PostController@edit')->name('edit');
        Route::post('update/{post}', 'PostController@update')->name('update');
        Route::post('destroy/{post}', 'PostController@destroy')->name('destroy');
    });

    Route::group(['prefix' => 'user', 'as' => 'users.', 'namespace' => 'Admin'], function () {
        Route::get('index', 'UserController@index')->name('index');
        Route::get('create', 'UserController@create')->name('create');
        Route::post('store', 'UserController@store')->name('store');
        Route::get('show/{user}', 'UserController@show')->name('show');
        Route::get('edit/{user}', 'UserController@edit')->name('edit');
        Route::post('update/{user}', 'UserController@update')->name('update');
        Route::post('destroy/{user}', 'UserController@destroy')->name('destroy');
    });
});
```
`$ php artisan route:list`をすると、最初のルーティング例と全く変わらないことがわかると思います。


# 最後に
改善点やこういうのあるよ！というのがありましたら、どんどんコメント下さい！

少しでも役に立った！という時は、いいねをポチッとして
フォローしてくださると嬉しいです、、、笑

役に立たなかった時は、怒らないでコメント頂けますと幸いです笑

Twitterもやってますので、よかったら見てみてくださいね！
https://twitter.com/jefftechsaku