Laravelの「ルーティング」ってどう使う?図解でわかる基本のキ

Table of Contents

Laravelの「ルーティング」ってどう使う?図解でわかる基本のキ

Laravelのルーティングは、ユーザーのリクエスト(URLやHTTPメソッド)をコントローラや処理へ結びつける、アプリの「入り口」です。
初心者向け 本記事では、Laravelルーティング図解コード例でやさしく解説します。
これから学ぶあなたでも「どのURLにアクセスしたら、どの処理が動くのか?」がスッと分かるように、実務でそのまま使える書き方まで丁寧に紹介します。✨

キーワード: Laravel / ルーティング / 初心者 / コントローラ / ミドルウェア / 名前付きルート / ルートモデルバインディング

ルーティングの超基本:URL→処理の流れを図で理解 🗺️

ルーティングは「どのURLにアクセスしたら、どの処理(クロージャ or コントローラのメソッド)が動くか」を決める仕組みです。Laravelでは主に routes/web.php に定義します。

図解:HTTPリクエストの流れ(初心者イメージ)
[ブラウザ]  --GET /articles/42-->  [Laravel ルータ]
                                   │  URLやHTTPメソッドを判定
                                   ├─> [ミドルウェア(任意): 認証/CSRF/ログなど]
                                   └─> [コントローラ ArticlesController@show]
                                           │
                                           └─> [ビュー resources/views/articles/show.blade.php]
        

ポイント: ルータは単なる経路案内人ではなく、ミドルウェアバリデーションルートモデルバインディングなど、アプリケーションの安全性・生産性を高める多くの機能と連携します。初学者でも「URLの設計」からはじめて、小さく便利な機能を足し算していくのがおすすめです。💡

実践:web.phpでの基本ルートを書いてみよう ✍️

まずは、routes/web.php に最小限のルートを書いてみましょう。Laravel初心者が最初につまずきやすいのは「書き方のパターンが多い」こと。ここでは、クロージャコントローラの2パターンからスタートします。

クロージャで手早く試す(超入門)

// routes/web.php
use Illuminate\Support\Facades\Route;

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

Route::get('/greet', function () {
    return view('greet'); // resources/views/greet.blade.php を返す
});

小さな検証や、Bladeの表示確認はこれで十分。ただし、アプリが大きくなるとコントローラに分離したほうが見通しが良くなります。

コントローラに振り分ける(実務向け)

// routes/web.php
use App\Http\Controllers\ArticleController;

Route::get('/articles', [ArticleController::class, 'index']);   // 一覧
Route::get('/articles/{id}', [ArticleController::class, 'show']); // 詳細
// app/Http/Controllers/ArticleController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function index()
    {
        // 記事一覧を取得してビューへ
        $articles = [
            ['id' => 1, 'title' => 'Laravelルーティング入門'],
            ['id' => 2, 'title' => '初心者向けBladeテンプレート']
        ];
        return view('articles.index', compact('articles'));
    }

    public function show($id)
    {
        // 実務ではEloquentでDBから取得
        return view('articles.show', ['id' => $id]);
    }
}
Tips: URLの設計は「名詞の複数形」を基本にするとRESTfulで読みやすくなります(例:/articles, /users)。👍

コントローラとつなぐ:メソッド/リソース/名前付きルート

ルートは名前をつけたり、リソースコントローラで一括定義できたりします。URLを生成するときに名前付きルートはとても便利です。

名前付きルート(route()でURL生成)

// routes/web.php
use App\Http\Controllers\ArticleController;

Route::get('/articles', [ArticleController::class, 'index'])->name('articles.index');
Route::get('/articles/{id}', [ArticleController::class, 'show'])->name('articles.show');
// Blade内でURL生成(resources/views/articles/index.blade.php)
@foreach ($articles as $article)
  <a href="{{ route('articles.show', ['id' => $article['id']]) }}">
    {{ $article['title'] }}
  </a>
@endforeach

こうしておけば、URLの変更があってもルート名はそのまま使えるので、テンプレートの修正が減って安心です。🎯

リソースコントローラでCRUDを一括定義

// routes/web.php
use App\Http\Controllers\ArticleController;

Route::resource('articles', ArticleController::class);
HTTPメソッド URL コントローラ@メソッド 名前
GET/articlesindexarticles.index
GET/articles/createcreatearticles.create
POST/articlesstorearticles.store
GET/articles/{article}showarticles.show
GET/articles/{article}/editeditarticles.edit
PUT/PATCH/articles/{article}updatearticles.update
DELETE/articles/{article}destroyarticles.destroy
小技: 不要なアクションを除外したい場合は only / except を使います。
Route::resource('articles', ArticleController::class)->only(['index','show']);

便利ワザ:パラメータ、バリデーション、正規表現制約

ルーティングではURLの一部をパラメータとして受け取れます。必須任意正規表現制約を活用して、URLの表現力を高めましょう。🧩

必須&任意パラメータ

// 必須パラメータ
Route::get('/users/{id}', function ($id) {
    return "User ID: {$id}";
});

// 任意パラメータ(デフォルト値を用意)
Route::get('/hello/{name?}', function ($name = 'Guest') {
    return "Hello, {$name}!";
});

正規表現で形式を縛る(数字だけ 等)

Route::get('/orders/{orderId}', function ($orderId) {
    return "Order: {$orderId}";
})->where('orderId', '[0-9]+');

複数条件やグローバル制約

// 複数のwhere
Route::get('/shops/{area}/{code}', function ($area, $code) {
    return "Area={$area}, Code={$code}";
})->where([
    'area' => '[a-z]+',
    'code' => '[0-9]{3}'
]);

// 全体に適用する場合:RouteServiceProvider などで pattern を設定
注意: 正規表現は強力ですが、過度に厳しくするとURLの表現力を下げることがあります。必要最小限でOK。😉

セキュアに:ミドルウェア、CSRF、認証ガードの基礎 🔒

初心者が覚えておくと安心なのがミドルウェア。ルートに「認証」や「ログ記録」などの共通処理を適用できます。
ポイント コードの重複を減らし、セキュリティや可読性をグッと上げられます。

認証が必要なページを守る

Route::middleware('auth')->group(function () {
    Route::get('/dashboard', function () {
        return view('dashboard');
    });
});

CSRF保護(フォーム必須)

<form method="POST" action="{{ route('articles.store') }}">
  @csrf
  <input type="text" name="title">
  <button type="submit">保存</button>
</form>

APIルート(routes/api.php)はCSRFが標準で無効になっている等、ファイルによって前提が違う点も覚えておきましょう。🔍

さらに使える:グループ化、プレフィックス、サブドメイン

ルートが増えてきたらグループ化で整理しましょう。URLに共通の接頭辞(prefix)をつけたり、ミドルウェアをまとめて適用したりできます。

管理画面をまとめて保護(prefix + middleware)

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

サブドメインでテナントを切り替える(応用)

Route::domain('{account}.example.com')->group(function () {
    Route::get('/dashboard', function ($account) {
        return "Tenant={$account}";
    });
});
整理整頓術: グループでname()を併用すると、admin.のように名前にも接頭辞をつけられて便利です。
例:Route::name('admin.')->prefix('admin')->group(...)

ルートモデルバインディングでEloquentと直結

ルートモデルバインディングを使うと、URLのIDからEloquentモデルを自動解決できます。コントローラがすっきりして、初心者でも読みやすいコードに。🌱

暗黙的バインディング(推奨)

// routes/web.php
use App\Models\Article;

Route::get('/articles/{article}', function (Article $article) {
    return view('articles.show', compact('article'));
})->name('articles.show');

これだけで、/articles/42 にアクセスすると自動的に Article::findOrFail(42) 相当が動き、$article にモデルが入ります。存在しなければ404を返します。🎯

キーをカスタム(スラッグ対応)

// app/Models/Article.php
public function getRouteKeyName()
{
    return 'slug'; // /articles/laravel-routing-basic のようなURLに
}

よくあるエラー&デバッグのコツ 🐛

ルーティングは小さな書き間違いで404になりがち。初心者がつまずきやすいポイントをまとめました。

キャッシュに注意(変更が反映されない)

php artisan route:clear   # ルートキャッシュをクリア
php artisan config:clear  # 設定キャッシュをクリア
php artisan cache:clear   # アプリ全体のキャッシュをクリア

名前付きルートの衝突

同じ名前を重複定義すると生成先が意図せず変わることがあります。php artisan route:listで確認し、名前の一意性を保ちましょう。

メソッド違い(GET/POSTなど)

フォームはPOST、更新はPUT/PATCH、削除はDELETE。HTTPメソッドが違うと同じパスでも別ルートとして扱われます。

便利コマンド:
php artisan route:list --path=articles --columns=Method,URI,Name,Action,Middleware
出力で「どのURLにどのミドルウェア・どのコントローラが紐づくのか」を一望できます。👀

実例で理解:小さな記事CRUDをルーティングから作る

ここでは記事一覧・作成・詳細を最小構成で作ります。ルーティング→コントローラ→ビューの順で関連付ける流れを体験しましょう。🧪

ルーティング定義

// routes/web.php
use App\Http\Controllers\ArticleController;

Route::get('/articles', [ArticleController::class, 'index'])->name('articles.index');
Route::get('/articles/create', [ArticleController::class, 'create'])->name('articles.create')->middleware('auth');
Route::post('/articles', [ArticleController::class, 'store'])->name('articles.store')->middleware('auth');
Route::get('/articles/{article}', [ArticleController::class, 'show'])->name('articles.show');

コントローラ(要点のみ)

// app/Http/Controllers/ArticleController.php
namespace App\Http\Controllers;

use App\Models\Article;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function index()
    {
        $articles = Article::latest()->paginate(10);
        return view('articles.index', compact('articles'));
    }

    public function create()
    {
        return view('articles.create'); // 認証必須
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'title' => ['required','string','max:255'],
            'body'  => ['required','string'],
        ]);
        $article = Article::create($data);
        return redirect()->route('articles.show', $article)->with('status', '記事を作成しました 🎉');
    }

    public function show(Article $article)
    {
        return view('articles.show', compact('article'));
    }
}

Blade(リンク生成の例)

<!-- resources/views/articles/index.blade.php -->
<h1>記事一覧</h1>
@auth
  <a href="{{ route('articles.create') }}" class="btn btn-primary">新規作成</a>
@endauth

<ul>
@foreach ($articles as $article)
  <li><a href="{{ route('articles.show', $article) }}">{{ $article->title }}</a></li>
@endforeach
</ul>

{{ $articles->links() }}
学びの要点: route()name() をセットで覚える/middleware() で保護する/Route Model Bindingでモデルを自動解決。これでLaravel ルーティング 初心者から一歩先へ!🚀

まとめ&次の一歩

  • ルーティングは「URLと処理の対応表」。最初は web.php に小さく書いて動かそう。
  • アプリが育ったらコントローラへ分離、名前付きルートでURL生成を安定化。
  • ミドルウェアグループ化で安全・整理・拡張性をUP。
  • ルートモデルバインディングでEloquentと直結、コードをシンプルに。

次はリソースコントローラフォームリクエストを組み合わせて、ルーティングの外側(バリデーション)まで一貫した設計に挑戦してみてください。あなたのLaravel力、確実に伸びます。💪

FAQ(初心者がつまずくポイント集)

Q. web.php と api.php の違いは?

web.php は主にブラウザ向け(セッション・CSRFが有効)、api.php はAPI向け(ステートレス、CSRF無効など)です。画面を持つ通常のWebアプリは web.php に定義しましょう。

Q. 404が出るのはなぜ?

ルート定義の順番やHTTPメソッド違い、パラメータ制約の厳しさ、キャッシュの影響が原因になりがち。php artisan route:listphp artisan route:clear を活用して確認しましょう。

Q. 名前付きルートは必須?

必須ではありませんが、テンプレートでのURL生成やリダイレクト時にとても便利です。URLが変わってもルート名はそのまま使えるので、保守性が上がります。

Q. ミドルウェアはどこで設定する?

個別のルートに ->middleware('auth') のように付けたり、グループ化(Route::middleware([...])->group())でまとめて適用できます。app/Http/Kernel.php によく使うミドルウェアが登録されています。

Q. ルートが増えて見づらい…どう整理する?

prefixnamemiddleware を組み合わせてグループ化しましょう。管理画面やAPI、公開サイトなど、役割ごとにひとまとめにできます。

Q. ルートモデルバインディングで見つからない時は?

URLパラメータ名とモデルのキー設定(getRouteKeyName())が合っているか、データが存在するかを確認しましょう。見つからない場合は自動的に404になります。

Q. SEO的にURLはどう設計する?

英単語の複数形でリソースを表し、IDではなくスラッグを使うと読みやすくなることがあります(例:/articles/laravel-routing-basic)。ただし実務要件と相談の上で決めましょう。

今日の学びを手を動かして定着しよう ✅

あなたのLaravelアプリに、名前付きルートミドルウェアルートモデルバインディングのいずれかを今すぐ1つ追加してみましょう。
小さな一歩が、読みやすく保守しやすいアプリを作ります。🚀

用語ミニ辞典(初心者向け)

  • ルーティング: URLやHTTPメソッドを処理へ結びつける仕組み。
  • 名前付きルート: ルートに名前をつけて、route('name')でURL生成。
  • ミドルウェア: 認証やログなど共通処理をルートに挟み込む仕組み。
  • ルートモデルバインディング: URLの値からEloquentモデルを自動取得。
  • リソースコントローラ: CRUD用のルートを一括定義する仕組み。