おススメ記事
【Laravel入門】ルーティングの基本と実践活用まとめ:仕組み・書き方・落とし穴まで

Laravelのルーティングは開発を始めたばかりの人は、「なんとなく動くからいいや」と思って使っている機能のひとつかもしれない。

そんなLaravelのルーティングについてこの記事では、Laravelのルーティングについて、基本から詳しめにわかりやすく整理していこうと思います。

ルーティングとは何か?

ルーティングとは、ユーザーからのリクエスト(URL)を、Laravel側の処理に紐付けする仕組みです。

たとえば、/about というエンドポイント(アクセス先のURL)にリクエストが来たら、AboutController index() メソッドを実行する──というような動作を定義できます。

エンドポイント(endpoint)ってなに?

クライアントがアクセスするURLの到達点
「このURLを叩いたら、こういう処理がされるよ」っていう接続口みたいなやつ。

  • GET /api/users → ユーザー一覧を取得するエンドポイント
  • POST /login → ログイン処理を行うエンドポイント

ルート定義

Laravelの基本的なルート定義は以下のような形になります。

use Illuminate\Support\Facades\Route;

Route::get('/hello', function () {
return 'Hello, Laravel!';
});

この場合、/hello にGETアクセスされたときに、"Hello, Laravel!" という文字列を返す。
こう記述すると https://自分で取得したドメイン/hello にアクセスすると、Hello Laravelという文字列が表示されます。

Laravelでは、HTTPメソッドごとにルート定義を使い分けられます。

  • Route::get():主にデータの取得に使います(読取り専用)。
  • Route::post():新しいデータの作成など。サーバー側の状態が変わる。
  • Route::put() / Route::patch():データの更新用。厳密には用途に違いがあります。
  • Route::delete():データの削除。
  • Route::match(['get', 'post'], ...):複数メソッド対応。
  • Route::any():全部のメソッドに反応。テスト用や雑な用途向け。

※ HTTPメソッドにはそれぞれ意味や“設計上のルール”がありますが、機会があればAPI設計と絡めて記事を書きたいと思います。

コントローラーを使ったルーティング

実際の開発では、無名関数よりもコントローラーを使うケースが一般的。

Route::get('/users', [UserController::class, 'index']);

このように書くと、UserControllerindex() メソッドが呼び出される。
App\Http\Controllers\UserController にIndexメソッドが生えてれば処理が実行されます。

ルートパラメータとモデルバインディング

プレースホルダ付きルート

Route::get('/users/{id}', [UserController::class, 'show']);

URLの中に {id} のようなプレースホルダを入れることで、
例えば /users/42 にアクセスされたときに、show($id)42 が渡ってきます。

// app/Http/Controllers/UserController.php


public function show($id) # ここの$idに42が渡ってくるよ!
{
    $user = User::findOrFail($id);
    // 必要に応じて、データをレスポンスやビューへ渡す
}

こういった形式のURLの {} の部分は 「パスパラメータ(path parameter)」 と呼ばれます。
リクエストされたURLの“どの部分を変数として受け取るか”を指定する仕組みです。

モデルバインディング

Laravelの便利な機能として、「ルートモデルバインディング」があります。
{user} の部分にIDを指定すると、自動的に User モデルのインスタンスが注入されます。
簡単なものを作る時に便利かもしれませんね。

Route::get('/users/{user}', [UserController::class, 'show']);
// app/Http/Controllers/UserController.php

use App\Models\User;

public function show(User $user) {
    return view('user.show', compact('user'));
}

モデルを明示的に取得する必要がなくなるので、コードもスッキリします。

Route::resource() の便利さと注意点

Laravelには、RESTfulなルートを一気に定義できる Route::resource() があります。

Route::resource('posts', PostController::class);

これだけで以下の7つのルートが生成される:

HTTPURLアクション用途
GET/postsindex一覧表示
GET/posts/createcreate作成フォーム
POST/postsstore作成処理
GET/posts/{post}show詳細表示
GET/posts/{post}/editedit編集フォーム
PUT/PATCH/posts/{post}update更新処理
DELETE/posts/{post}destroy削除処理

REST(Representational State Transfer)とは、Webの設計原則のひとつで、
「URLとHTTPメソッドを組み合わせて、リソース(=データ)を操作する」考え方です。

RESTについてある程度知りたい人のための記事

GET /posts で一覧取得、POST /posts で作成、DELETE /posts/1 で削除…といった形で、ルール化されています。

LaravelではこのRESTのルールに従ったルーティングを「resource()」で簡単に作れます。

LaravelはRestと親和性が高いことが伺えますね。

必要なアクションだけ使いたい場合は only() を使うと便利。

Route::resource('posts', PostController::class)->only(['index', 'show']);

7つもルート要らないよ!!って人は確実にいるので、こうやって利用するルートを限定することもできるんですね。

名前付きルートとroute()ヘルパー

ルートに名前をつけると、URLを直接書かずにリンク先を指定できます。

Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');

エンドポイントに影響があるわけではないですが、実はこれってとっても便利なんですよ。

Route::get('/dashboard', [DashboardController::class, 'index']);

と名前をつけずにルートを定義していました。

で、名前をつけてないので、至る所にこんな実装があったとします。

// たとえばコントローラーとかビューで
return redirect('/dashboard');
<a href="/dashboard">ダッシュボード</a>

この状態でえらいおじさんが

🧓 「このurlのdashbordさー、homeにしてくんない?」

どこに /dashboard 書いたか全部探す旅が始まる😱

  • Bladeテンプレート全部検索
  • コントローラーの redirect() チェック
  • JavaScriptで埋め込まれてないかチェック
  • ページネーションやリンク生成も再確認

ということが起きるので、nameは設定しておくと地味に便利です。必ず設定しましょう。

ミドルウェアとルート制御

Laravelでは、「このルートは特定の条件を満たしたユーザーだけがアクセスできるようにしたい」といった制限をかけたいときに、ミドルウェア(middleware)を使います。

たとえば、ログインしていないユーザーをアクセス禁止にしたい場合は、auth ミドルウェアを使います。

Route::middleware(['auth'])->group(function () {
    Route::get('/profile', [ProfileController::class, 'show']);
});

このように書くと、/profile へのアクセスにはログイン済みであることが必須になります。
auth ミドルウェアが「ログインしてない人はリダイレクトさせる」処理を自動で担当してくれるわけです。

この仕組みは、Laravel Breeze や Jetstream などの公式スタートキットでも標準で使われており、
認証付きページや会員専用ページなどを作るときの基本パターンとしてよく使われます。

マジで爆速でLaravelエンジニアになる方法はこれしかない(無料)

LaravelBreezeについては↑で構築ハンズオンやってます。爆速でLaravelエンジニアになりたい方はどうぞ。

Route::group() でルートをまとめよう

Laravelでは、複数のルートに対して共通の条件や設定をまとめて指定したいときに、Route::group() を使います。

最もよく使われるのは以下の3つ:

  • URLの先頭に共通の文字列をつけたい(prefix
  • ミドルウェアをまとめて適用したい(middleware
  • 名前付きルートの接頭語をつけたい(as

例1:URLに共通の prefix をつける

Route::prefix('admin')->group(function () {
    Route::get('/users', [AdminUserController::class, 'index']);
    Route::get('/posts', [AdminPostController::class, 'index']);
});

これで定義されるルートは:

  • /admin/users
  • /admin/posts

いちいち admin/ って書かなくて済むし、保守性が爆上がり。

例2:共通のミドルウェアをまとめてかける

Route::middleware(['auth', 'verified'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    Route::get('/settings', [SettingsController::class, 'edit']);
});

すべてのルートに authverified ミドルウェアが適用されます。
「ログインしてて、メール認証も済んでる人だけアクセスOK」のゾーンがまとめて作れて便利。

これが一番良く使うパターンかも知れない。

例3:名前付きルートの prefix を設定する

Route::name('admin.')->prefix('admin')->group(function () {
    Route::get('/users', [AdminUserController::class, 'index'])->name('users.index');
});

このようにすると、ルート名は自動的に admin.users.index になります。

例4:これらを全部まとめて使うとこうなる

Route::prefix('admin')
    ->name('admin.')
    ->middleware('auth')
    ->group(function () {
        Route::get('/dashboard', [AdminDashboardController::class, 'index'])->name('dashboard');
        Route::get('/users', [AdminUserController::class, 'index'])->name('users.index');
    });

URLは: /admin/dashboard
ルート名は: admin.dashboard
ミドルウェア: auth(ログイン必須)

ルーティング時のバリデーション

Laravelのルーティングでは、パスパラメータに対してバリデーションルールを設定することができます。
これは、「変な値が来たら最初から処理しない」という安全設計につながる便利な機能です。

正規表現でパラメータを制御する: where()

Route::get('/users/{id}', [UserController::class, 'show'])
    ->where('id', '[0-9]+');

このように書くことで、{id} に対して **「数字だけ」**という制限をかけられます。
/users/abc のようなリクエストはこのルートにマッチせず、404になります。

数字だけ許可:whereNumber()

Route::get('/products/{product}', [ProductController::class, 'show'])
    ->whereNumber('product');

[0-9]+ と書く代わりに、Laravelには数字専用のショートカットメソッドがあります。
これで同じことがよりシンプルに書けます。

他にも使えるバリデーションメソッド

メソッド説明
whereAlpha()アルファベットのみ許可
whereAlphaNumeric()英数字を許可
whereIn('param', ['a', 'b', 'c'])特定の候補だけ許可(Laravel 10〜)

routes/web.php と routes/api.php の違い

Laravelの routes ディレクトリには、いくつかルート定義ファイルが用意されています。
その中でも特に使うのが web.phpapi.php
どっちも「ルーティングを書く場所」なんだけど、使いどころと裏で働いてる仕組みが違うんです。

主な違い

特徴web.phpapi.php
想定される用途通常のWebページ(HTML、Blade等)API通信(JSONなど)
自動適用されるミドルウェアweb ミドルウェアグループapi ミドルウェアグループ
セッションの有無ある(Session使える)ない(Stateless)
CSRF保護ありなし
URLのprefixなし(素のURL)自動で /api が付与される
レスポンス形式HTML、ビューなどJSONが基本

具体例で見る違い

// routes/web.php
Route::get('/dashboard', [DashboardController::class, 'index']);
// routes/api.php
Route::get('/users', [Api\UserController::class, 'index']);

上記の /users は、実際には /api/users にマッピングされます(prefix自動付与)。
一方 /dashboard はそのまま /dashboard で使われます。

CSRFトークン、WebにはあるけどAPIにはない

  • web.php ではフォームやPOSTリクエストを送るときに CSRFトークン(@csrf が必須。
  • api.phpCSRF保護が無効になっていて、そもそも「認証のやり方が違う」前提(トークンベース認証など)。

なので、VueやReactとLaravelのAPI連携するときは、api.php に書いたルートを使うのが自然。

CSRFトークンってなに?

フォームなどを通じた意図しないリクエスト(悪意ある第三者による)を防ぐためのセキュリティ対策です。Laravelでは web.php に定義されたルートに対してPOSTリクエストを送るとき、CSRFトークンが自動的に必要になります。

設定ファイルで明確に役割が分かれてる

app/Http/Kernel.php を見ると、以下のように定義されてます

protected $middlewareGroups = [
    'web' => [
        // セッション、CSRF、クッキーなど
    ],
    'api' => [
        'throttle:api',
        'bindings',
    ],
];

つまり、同じルーティング構文でも、どこに書いたかによって内部で動いてる処理が変わります。

同じ Route::get() という構文でルートを定義していても、それを web.php に書くか、api.php に書くかによって、自動で適用されるミドルウェアやリクエストの前提条件が大きく変わります。

たとえば web.php に書いたルートは、セッションやクッキー、CSRF保護が有効になっており、フォーム送信やログイン後のページなど通常のWebアプリ向けに最適化されています。

一方で api.php に書いたルートは、ステートレス(状態を持たない)通信を前提としており、CSRFは無効・セッションは使わず、レスポンスもJSONが基本となるため、API連携やモバイルアプリ用のエンドポイントに適しています。

Laravelが裏で自動的に「このルートはWeb用だな」「こっちはAPI用だな」と判別して、それに合った処理の流れを用意してくれているというわけです。

まとめてみるとこう

書く場所自動的に有効になるミドルウェア状態想定用途
web.phpweb グループ(CSRF, session, cookie)ステートフルHTMLベースのWebページ
api.phpapi グループ(throttle, bindings)ステートレスJSON API、モバイル、SPA通信

Laravelルーティングで困ったときのトラブルシュートTips

Laravelのルーティングは基本的にわかりやすい設計になっていますが、変更が反映されない・想定と違う挙動をするといったトラブルに遭遇することもあります。
そんなときは、以下のコマンドやチェック項目を試してみましょう。

ルート一覧を確認する

ルートが正しく登録されているか、一目で確認できるコマンドがこれです。

php artisan route:list
  • URI / メソッド / コントローラーの対応関係が一覧表示されます。
  • 特に Route::resource() を使ったときに、どのルートが自動で作られたか確認するのに超便利。
  • --name--method=POST などのオプションでフィルタも可能。

キャッシュをクリア

ここに乗ってない場合、実装ミスを除けば大体キャッシュが原因です。

php artisan route:clear

これでルート周りのキャッシュをクリアできます。

これで無理なら

php artisan optimize:clear

これで全キャッシュクリアできます。

おわりに

Laravelのルーティングは、一見シンプルな構文に見えて、
その裏には認証、バリデーション、ミドルウェア、ルートグループ化、さらにはWebとAPIの明確な住み分けなど、実に多くの機能が詰め込まれています。

今回の記事では、ただルートを書くのではなく、「なぜこの書き方なのか」「どこに書くべきなのか」といった設計視点も交えて解説しました。

スポンサーリンク

この記事が気に入ったら
フォローしよう

最新情報をお届けします

Twitterでフォローしよう

おすすめの記事