Laravel の Route(ルーティング)は、URLへのリクエストをどのコントローラやクロージャで処理するかを結びつける仕組みです。routes/web.php に1行書くだけで動き始める手軽さがある一方、パラメータの必須/任意、名前付きルート、リソースルート、キャッシュまわりでつまずきやすいポイントも多くあります。本記事では、Laravel 13 環境で実際にルートを定義・実行して動作を確認しながら、Route の基本から実務で使う設定までを整理します。
Laravelのルーティングとは
ルーティングとは、ブラウザやAPIクライアントから届いたHTTPリクエスト(URL+メソッド)を、それを処理するコントローラのメソッドやクロージャに振り分ける仕組みです。Laravelでは Route ファサードを使い、routes/ ディレクトリ配下のファイルにルートを定義します。
| ファイル | 役割 | URLの先頭 |
|---|---|---|
routes/web.php | ブラウザ向けの画面表示ルート(セッション・CSRF保護あり) | プレフィックスなし |
routes/api.php | API向けルート(ステートレス、install:api実行時のみ生成) | /api |
routes/console.php | Artisanコマンド定義 | — |
Laravel 11以降の変更点:かつて存在した RouteServiceProvider は廃止され、ルートファイルの登録は bootstrap/app.php の withRouting() で行うようになりました。実際に Laravel 13 で新規プロジェクトを作成すると、bootstrap/app.php は次の内容で生成されます。
// bootstrap/app.php(Laravel 13 の初期状態)
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
// ...
初期状態では api: の指定がなく、routes/api.php 自体も存在しません。API開発では php artisan install:api を実行して初めて routes/api.php が生成され、withRouting() にも api: __DIR__.'/../routes/api.php' が自動追加されます(詳細は後述)。古いバージョン向けの記事や書籍を参考にする場合、この構造の違いに注意してください。
ルート定義の基本
routes/web.php の先頭で Route ファサードを use し、HTTPメソッドに対応するメソッドでルートを定義します。
use Illuminate\Support\Facades\Route;
Route::get('/welcome', function () {
return 'Hello Laravel';
});
ブラウザで /welcome にアクセスすると Hello Laravel がそのまま返ることを、実際に php artisan serve を起動して確認済みです。
主要なHTTPメソッド
| メソッド | 用途 | 記述例 |
|---|---|---|
Route::get() | ページ表示・データ取得 | Route::get('/users', ...) |
Route::post() | 新規作成・フォーム送信 | Route::post('/users', ...) |
Route::put() / patch() | 更新 | Route::put('/users/{id}', ...) |
Route::delete() | 削除 | Route::delete('/users/{id}', ...) |
Route::match(['get','post'], ...) | 複数メソッドを1つのルートで受ける | Route::match(['get','post'], '/search', ...) |
Route::any() | すべてのメソッドを受ける | Route::any('/webhook', ...) |
実機検証で確認した注意点:POST ルートに curl だけでアクセスするとCSRFトークンが無いため 419 Page Expired になります。web.php のルートは既定でCSRF保護が有効なため、フォームには @csrf、API的に叩きたい場合は routes/api.php(CSRF対象外)を使うのが正しい選択です。
ルートパラメータ
必須パラメータ
Route::get('/user/{id}', function ($id) {
return 'User '.$id;
});
// GET /user/42 -> "User 42"
任意パラメータ(デフォルト値付き)
Route::get('/greet/{name?}', function ($name = 'Guest') {
return "Hello, {$name}";
});
// GET /greet -> "Hello, Guest"
// GET /greet/Taro -> "Hello, Taro"
どちらも実際にリクエストを送って、想定どおりの文字列が返ることを確認しています。
正規表現によるパラメータ制約(where)
Route::get('/product/{id}', function ($id) {
return 'Product '.$id;
})->where('id', '[0-9]+');
この状態で /product/123 は Product 123 を返しますが、/product/abc は制約に一致せずルート自体が「存在しない」扱いになります。検証してわかった点200で応答してしまうため、本番でエラーを正しく検知したい場合は、フォールバックの実装内容やログ監視もあわせて設計する必要があります。
コントローラーとの連携
クロージャで書いたルートはコードの見通しが悪くなりやすいため、実務ではコントローラーに処理を切り出します。
php artisan make:controller UserController
use App\Http\Controllers\UserController;
// 配列構文でコントローラのメソッドを指定する(現在の標準的な書き方)
Route::get('/users/{user}', [UserController::class, 'show']);
文字列で 'UserController@show' のように書く記法は古いLaravelのチュートリアルでよく見かけますが、現行バージョンでは [UserController::class, 'show'] の配列構文が推奨です。クラス名をタイプミスしてもIDEやツールで検出しやすくなります。
リソースルート
CRUD操作を持つコントローラは Route::resource() で一括登録できます。
Route::resource('photos', PhotoController::class);
php artisan route:list で実際に生成されるルートを確認すると、以下の7本が一括登録されることがわかります。
| メソッド | URI | アクション | ルート名 |
|---|---|---|---|
| GET | /photos | index | photos.index |
| GET | /photos/create | create | photos.create |
| POST | /photos | store | photos.store |
| GET | /photos/{photo} | show | photos.show |
| GET | /photos/{photo}/edit | edit | photos.edit |
| PUT/PATCH | /photos/{photo} | update | photos.update |
| DELETE | /photos/{photo} | destroy | photos.destroy |
一部だけ使いたい場合は only / except でも絞り込めます。
Route::resource('photos', PhotoController::class)->only(['index', 'show']);
Route::resource('photos', PhotoController::class)->except(['destroy']);
ルートグループ
共通のプレフィックス・ミドルウェア・ルート名を複数のルートにまとめて適用したい場合は Route::prefix() / middleware() / name() を組み合わせてグループ化します。
Route::prefix('admin')->name('admin.')->middleware('auth')->group(function () {
Route::get('/dashboard', function () {
return 'admin dashboard';
})->name('dashboard');
});
// URL: /admin/dashboard
// ルート名: admin.dashboard
route('admin.dashboard') を実行すると http://localhost/admin/dashboard が生成されることを、php artisan tinker 上で確認しています。ネストが深くなるとルートの見通しが悪くなるため、グループ化は「共通設定が2〜3個以上まとまるとき」を目安にすると読みやすさを保てます。
名前付きルートとURL生成
name() でルートに名前を付けておくと、URLをハードコードせずに route() ヘルパで生成できます。パスを変更してもビュー側のコードを直す必要がないため、実務では積極的に使うべき機能です。
Route::get('/dashboard', function () {
return 'dashboard';
})->name('dashboard');
// どこからでも
$url = route('dashboard'); // http://localhost/dashboard
route() ヘルパの引数の渡し方、Eloquentモデルを直接渡した場合の挙動、UrlGenerationException が出るケースなど、より詳しい仕様は以下の記事にまとめています。
WebルートとAPIルートの違い
| 項目 | routes/web.php | routes/api.php |
|---|---|---|
| 用途 | 画面表示・フォーム送信 | 外部連携・SPA・モバイルアプリ向けAPI |
| 状態管理 | セッションを使用 | ステートレス(トークン認証が基本) |
| CSRF保護 | あり | なし |
| URLプレフィックス | なし | /api |
| 有効化 | 初期状態で利用可能 | php artisan install:api の実行が必要 |
実際にLaravel 13の新規プロジェクトで php artisan install:api を実行すると、routes/api.php が生成され、bootstrap/app.php の withRouting() にも api: __DIR__.'/../routes/api.php' が自動的に追記されることを確認しました。API専用のルート設計やRESTfulなCRUD構成、バージョニングの考え方は以下で詳しく解説しています。
ルートの確認・キャッシュ運用
| コマンド | 用途 |
|---|---|
php artisan route:list | 定義済みルート一覧を確認(--except-vendorで自作ルートのみ表示) |
php artisan route:cache | ルートをキャッシュして起動を高速化(本番推奨) |
php artisan route:clear | ルートキャッシュを削除 |
注意:クロージャを使ったルートは route:cache の対象外です。キャッシュしても反映されず「本番だけルートが効かない」という事象につながるため、本番運用するルートはコントローラー参照(配列構文)に統一するのが安全です。コマンドの詳細は以下でも解説しています。
よくある間違いとトラブルシュート
| 症状 | 原因 | 対処 |
|---|---|---|
| 特定のルートが呼ばれず別の処理が動く | ルートは上から順に評価されるため、汎用的な{id}ルートを固定パスより先に書いている | 固定パス(例: /user/profile)を{id}を含むルートより前に定義する |
| POSTすると419 Page Expired | web.phpのCSRF保護に対してトークンを送っていない | フォームに@csrfを追加する、またはAPIならroutes/api.phpを使う |
| ルートを変更したのに反映されない | 本番でroute:cache済みのまま、または定義にクロージャが含まれている | route:clear後にroute:cacheし直す。クロージャはコントローラーに移す |
| 存在しないURLで404ではなく200が返る | Route::fallback()が独自のレスポンスを200で返している | フォールバック内でabort(404)を呼ぶか、意図した挙動か設計を確認する |
route()でUrlGenerationException | ルート名の誤字、または必須パラメータ不足 | route:listでルート名を確認し、プレースホルダ名に合わせて引数を渡す |
まとめ
LaravelのRouteは、routes/web.phpへの1行の定義から始まり、パラメータ・コントローラー連携・リソースルート・グループ化・名前付きルートと機能を積み上げることで、大規模なアプリケーションのURL設計にも対応できます。Laravel 11以降はRouteServiceProviderが廃止されbootstrap/app.phpでの登録に一本化されている点、APIルートはinstall:apiを実行しないと使えない点は、特に情報が古いまま参照されがちなので押さえておきましょう。本番運用ではroute:cacheとクロージャ非対応の相性、CSRF保護によるPOSTの挙動もあわせて確認しておくと、思わぬハマりどころを避けられます。

コメント