25
17

More than 1 year has passed since last update.

Laravel 9.x ルーティングの解説

Last updated at Posted at 2022-09-20

ルーティングとは

LaravelのルーティングはHTTPリクエストのパスや内容に対応するコントローラに処理を渡す役目をします。

公式ドキュメント

ディレクトリ構成

ルーティングファイルは routes ディレクトリの中にいくつかあります。

ファイル 説明
api.php APIのルーティング
channels.php ブロードキャストチャンネルのルーティング
console.php コンソールのルーティング
web.php 一般のWebページのルーティング

主に利用するのは web.php または api.php になるかと思います。
LaravelをJSONで返すAPIとして利用する場合は api.php に書いていくことになります。

ビューを表示する

基本

routes/web.php
Route::get('/', function () {
    return view('welcome');
});

第一引数にルーティングパス、第二引数にコールバックまたはコントローラクラスを渡してルーティングに対応する処理を登録します。
コールバックの中にロジックを書くとルーティングファイルが肥大化するのでコントローラを登録しましょう。

ロジックがなく、シンプルに画面を表示したりリダイレクトのみ行いたい場合はコントローラを登録しなくても良いと思います。
また、view関数で view('welcome') と指定した場合、 resources/views/welcome.blade.php を指定したことになります。

補足: PHP7.4以降のコールバックの書き方

PHP7.4からはアロー関数が利用できるのでコールバックをよりシンプルに記述できます。

routes/web.php
Route::get('/', fn () => view('welcome'));

ビューを表示するシンプルな書き方

ビューを表示するだけなら view 関数を使うと良いでしょう。

routes/web.php
Route::view('/', 'welcome');

文字を返すだけでも表示してくれる

とりあえず文字だけ表示したいって時もシンプルに書けます。

routes/web.php
Route::get('health-check', fn () => 'ok');

ルーティングの優先順位について

Laravelのルーティングは上から定義した順に優先されます。

routes/web.php
Route::get('articles/{id}', [ArticleController::class, 'show']);
Route::get('articles/create', [ArticleController::class, 'create']);
  • '/articles/create' にアクセスした際、ルートパラメータ({id})に create が渡ってしまい、 show メソッドが呼ばれてしまいます。
routes/web.php
Route::get('articles/create', [ArticleController::class, 'create']);
Route::get('articles/{id}', [ArticleController::class, 'show']);
  • ルートパラメータ付きの定義は下に書くようにします。

リダイレクトする

単純なリダイレクト処理を行う場合は redirect 関数を使うと良いでしょう。
302 ステータスコードを返します。

routes/web.php
Route::redirect('here', 'there');

この例だと /here にアクセスすると /there にリダイレクトします。

HTTPリクエストメソッド

HTTPリクエストメソッドに対応するルーティングを登録できます。

routes/web.php
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

ルーティングとコントローラの命名

ルートは複数形(articles)
コントローラは単数形または複数形(ArticleController, ArticlesController)
名前付きルートはドット表記(articles.index)

で命名されることが多いです。

リソースコントローラ

routes/web.php
Route::resource('articles', ArticleController::class);

resource 関数で登録すると下記のルートを登録したのと同じ内容になります。

routes/web.php
Route::get('articles', [ArticleController::class, 'index'])->name('articles.index');
Route::get('articles/create', [ArticleController::class, 'create'])->name('articles.create');
Route::post('articles', [ArticleController::class, 'store'])->name('articles.store');
Route::get('articles/{article}', [ArticleController::class, 'show'])->name('articles.show');
Route::get('articles/{article}/edit', [ArticleController::class, 'edit'])->name('articles.edit');
Route::put('articles/{article}', [ArticleController::class, 'update'])->name('articles.update');
Route::delete('articles/{article}', [ArticleController::class, 'destroy'])->name('articles.destroy');

業務ではシンプルなCRUDではないことも多いのでリソースコントローラは使用せず、個別にルートを定義しています。

補足: リソースコントローラのテンプレートを作成

$ php artisan make:controller ArticleController --resource

--resource or -r オプションを付けてコマンドを実行するとリソースコントローラのテンプレートを生成できます。

app/Http/Controllers/ArticleController.php クリックして表示
app/Http/Controllers/ArticleController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ArticleController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

APIリソースコントローラ

routes/web.php
Route::apiResource('articles', ArticleController::class);

create, edit を除いたAPI用のルートを登録します。

routes/web.php
Route::get('articles', [ArticleController::class, 'index'])->name('articles.index');
Route::post('articles', [ArticleController::class, 'store'])->name('articles.store');
Route::get('articles/{article}', [ArticleController::class, 'show'])->name('articles.show');
Route::put('articles/{article}', [ArticleController::class, 'update'])->name('articles.update');
Route::delete('articles/{article}', [ArticleController::class, 'destroy'])->name('articles.destroy');

補足: APIリソースコントローラのテンプレートを作成

$ php artisan make:controller ArticleController --api
app/Http/Controllers/ArticleController.php クリックして表示
app/Http/Controllers/ArticleController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ArticleController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

補足: シングルアクションコントローラ

シングルアクションコントローラとは、単一のアクションのみ実行する責務を持つコントローラです。
publicメソッドを1つだけ持たせます。シングルアクションにすることで様々なメリットがあります。

  • コードの肥大化が防げる
    • 1ファイルの行数が減るため
  • 可読性が向上する
    • 使用しないプロパティやメソッドを読む必要がないため
  • メンテナンス性が向上する
    • クラスを分けることでコンフリクトが減る
    • 他のアクションの影響を受けないので削除しやすい
Route::get('articles', ArticleIndexControlelr::class)->name('articles.index');
$ php artisan make:controller ArticleIndexControlelr --invokable

--invokable or -i オプションを付けてコマンドを実行するとシングルアクションコントローラのテンプレートを生成できます。

app/Http/Controllers/ArticleIndexControlelr.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ArticleIndexControlelr extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function __invoke(Request $request)
    {
        //
    }
}

ルーティングでクラス名のみ渡した時は __invoke メソッドが実行されます。
https://www.php.net/manual/ja/language.oop5.magic.php#object.invoke

シングルアクションコントローラの場合は __invoke 以外にpublicのメソッドを持ってはいけません。(言語として強制される訳ではありませんが)
__construct のようなコンストラクタは除いて、シングルアクションコントローラ内でメソッドを分けたい場合はprivateメソッドを定義しましょう。

補足: ルーティングパスの命名規則

  • 前後にスラッシュを付けない
    • OK: Route::get('users', ...)
    • NG: Route::get('/users', ...)
    • NG: Route::get('users/', ...)
  • 名詞を使う、動詞は含めない
    • OK: Route::get('users', ...)
    • OK: Route::delete('users/{id}', ...)
    • NG: Route::get('getUsers', ...)
    • NG: Route::post('users/{id}/delete', ...)
  • 区切り文字はハイフンを使う
    • OK: Route::get('users/{id}/first-name', ...)
    • NG: Route::get('users/{id}/firstName', ...)
    • NG: Route::get('users/{id}/first_name', ...)
  • 小文字、特殊記号は避ける
  • ファイル拡張子を避ける
    • OK: Route::get('users', ...)
    • OK: Route::get('users.csv', ...)
  • コマンドではなく、リソースベースで命名する
    • OK: Route::post('users/{id}/activate', ...)
    • NG: Route::post('activate-users/{id}', ...)
  • Route::resourceを避ける
    • 使用するルートを1つ1つ定義する
    • ※これは個人の意見
  • アンチパターンを避ける

補足: ルーティング系コマンド

ルーティングの一覧を表示するコマンド

$ php artisan route:list

ルーティングをキャッシュするコマンド

$ php artisan route:cache

bootstrap/cache/routes-v7.php にキャッシュファイルが生成されます。
ちなみにLaravel 6.xまでは bootstrap/cache/routes.php に生成されていました。

ルーティングのキャッシュをクリアするコマンド

$ php artisan route:clear
25
17
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
17