> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 路由

> 說明 Laravel 的路由定義方式、路由參數與具名路由的基本觀念。

## 基本路由

Laravel 最基本的路由由 URI 與 closure 組成。
無需複雜的設定檔即可輕鬆定義路由與動作。

```php theme={null}
use Illuminate\Support\Facades\Route;

Route::get('/greeting', function () {
    return 'Hello World';
});
```

### 預設路由檔

所有 Laravel 路由都定義在 `routes/` 目錄的路由檔中。
Laravel 會根據 `bootstrap/app.php` 的設定自動載入這些檔案。

```mermaid theme={null}
flowchart LR
    A["進來的請求"] --> B{{"請求種類"}}
    B -->|"瀏覽器<br>Session / CSRF"| C["routes/web.php<br>web middleware 群組"]
    B -->|"API<br>無狀態"| D["routes/api.php<br>api middleware 群組"]
    B -->|"CLI 指令"| E["routes/console.php<br>Artisan 指令定義"]
    C --> F["Controller / Closure"]
    D --> F
    E --> G["指令 Handler"]
```

在 `routes/web.php` 定義瀏覽器用的路由。
此檔案中的路由會套用 `web` middleware 群組，提供 session、CSRF 保護、cookie 加密等功能。

```php theme={null}
use App\Http\Controllers\UserController;

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

### API 路由

若應用程式提供無狀態 API，可用 `install:api` Artisan 指令啟用 API 路由。

```shell theme={null}
php artisan install:api
```

`install:api` 指令會安裝 [Laravel Sanctum](/zh-TW/sanctum) 並建立 `routes/api.php` 檔案。
Sanctum 為第三方 API 消費者、SPA、行動應用提供簡潔而穩健的 API token 認證 guard。

```php theme={null}
Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:sanctum');
```

`routes/api.php` 中的路由是無狀態的，會套用 `api` [middleware 群組](/zh-TW/middleware)。
所有路由也會自動加上 `/api` URI 前綴，因此無需手動加上。
若要變更前綴，可編輯應用程式的 `bootstrap/app.php` 檔案。

```php theme={null}
->withRouting(
    api: __DIR__.'/../routes/api.php',
    apiPrefix: 'api/admin',
    // ...
)
```

### 可用的 HTTP 方法

路由器可為所有 HTTP 方法註冊路由。

```php theme={null}
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
```

需要回應多個 HTTP 方法的路由，使用 `match` 或 `any`。

```php theme={null}
Route::match(['get', 'post'], '/', function () {
    // ...
});

Route::any('/', function () {
    // ...
});
```

<Info>
  在 `web` 路由檔案中接收 `POST`、`PUT`、`PATCH`、`DELETE` 的 HTML 表單，一定要加上 `@csrf` 指示詞。
  否則請求會被拒絕。
</Info>

## 回傳 view 的路由

當路由只是回傳 view 時，使用 `Route::view` 可寫得更簡潔。

```php theme={null}
Route::view('/welcome', 'welcome');

// 傳資料給 view
Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
```

## 路由參數

### 必要參數

要動態取得 URL 的一部分時，可使用路由參數。
參數以 `{}` 包起來，在路由 callback 中作為引數接收。

```php theme={null}
Route::get('/user/{id}', function (string $id) {
    return '使用者 ID: ' . $id;
});
```

也可定義多個參數。

```php theme={null}
Route::get('/posts/{post}/comments/{comment}', function (string $postId, string $commentId) {
    return "文章 {$postId} 的留言 {$commentId}";
});
```

<Warning>
  路由參數不可包含 `/` 字元。
</Warning>

### 可選參數

要讓參數為可選，在參數名稱尾端加上 `?`，並為對應引數設定預設值。

```php theme={null}
Route::get('/user/{name?}', function (?string $name = null) {
    return $name ?? '訪客';
});

Route::get('/user/{name?}', function (?string $name = '訪客') {
    return $name;
});
```

### 以正則表達式限制參數

用 `where` 方法可以正則表達式限制參數格式。

```php theme={null}
Route::get('/user/{id}', function (string $id) {
    // ...
})->where('id', '[0-9]+');

Route::get('/user/{name}', function (string $name) {
    // ...
})->where('name', '[a-zA-Z]+');
```

常用樣式也可使用便利方法。

```php theme={null}
Route::get('/user/{id}/{name}', function (string $id, string $name) {
    // ...
})->whereNumber('id')->whereAlpha('name');
```

## 具名路由

使用具名路由，可在產生 URL 或 redirect 時以路由名稱參照。

```php theme={null}
Route::get('/user/profile', function () {
    // ...
})->name('profile');
```

### 產生具名路由的 URL

要從路由名稱產生 URL，使用 `route` helper。

```php theme={null}
// 產生 URL
$url = route('profile');

// 產生附參數的 URL
$url = route('user.show', ['id' => 1]);
```

### Redirect

```php theme={null}
return redirect()->route('profile');
```

## 路由群組

可將相關路由分組，共同套用 middleware、controller、前綴等設定。

```mermaid theme={null}
flowchart TD
    A["HTTP 請求"] --> B["路由器"]
    B --> C{{"是否有<br>符合的路由？"}}
    C -->|"沒有"| D["404 回應"]
    C -->|"有"| E["確認路由的 middleware"]
    E --> F{{"是否通過<br>middleware？"}}
    F -->|"拒絕"| G["Redirect /<br>錯誤回應"]
    F -->|"通過"| H["執行 controller /<br>closure"]
    H --> I["產生回應"]
    I --> J["送往用戶端"]
```

### Middleware

```php theme={null}
Route::middleware(['auth'])->group(function () {
    Route::get('/dashboard', function () {
        // 只有已認證使用者可存取
    });

    Route::get('/account', function () {
        // 只有已認證使用者可存取
    });
});
```

### Controller

可將使用相同 controller 的路由分組。

```php theme={null}
use App\Http\Controllers\OrderController;

Route::controller(OrderController::class)->group(function () {
    Route::get('/orders', 'index');
    Route::post('/orders', 'store');
    Route::get('/orders/{id}', 'show');
});
```

### 前綴

可為路由 URI 加上共同前綴。

```php theme={null}
Route::prefix('admin')->group(function () {
    Route::get('/users', function () {
        // 可存取 /admin/users
    });
    Route::get('/posts', function () {
        // 可存取 /admin/posts
    });
});
```

## 檢視路由一覽

要一覽所有已定義的路由，使用 Artisan 指令：

```shell theme={null}
php artisan route:list
```

若要一併顯示 middleware 資訊：

```shell theme={null}
php artisan route:list -v
```

若要只顯示以特定 URI 開頭的路由：

```shell theme={null}
php artisan route:list --path=user
```

## 後續步驟

<Card title="View" icon="eye" href="/zh-TW/views">
  學習建立 view 並從 controller 傳入資料的方法。
</Card>


## Related topics

- [路由](/zh-TW/packages/laravel-bluesky/route.md)
- [請求生命週期](/zh-TW/lifecycle.md)
- [Laravel Socialite（社群認證）](/zh-TW/socialite.md)
- [Laravel Sentinel — 路由保護 Middleware 調查](/zh-TW/blog/sentinel-introduction.md)
- [URL 生成](/zh-TW/urls.md)
