哈囉,大家好!在前面的文章中,我們已經建立了資料庫結構,並使用 Model 與資料庫進行互動。現在,我們準備開始開發後端 API。在這個過程中,路由(Route) 扮演著至關重要的角色,決定了使用者的請求如何被處理。
由於篇幅的關係,我們將這個主題分成兩部分:今天我們專注於 路由設定,下一篇則會深入探討 控制器(Controller) 的實作。
在 Laravel 中,路由是所有請求的入口。它負責將 HTTP 請求導向適當的控制器方法或閉包函式。透過靈活的路由設定,我們可以:
Laravel 提供了多種方式來定義路由,讓我們來看看如何手動定義 API 路由,並使用群組和前綴來組織路由。
打開 routes/api.php,你會看到預設的內容。我們可以在這裡新增我們的 API 路由。
我是不太習慣使用 Route::apiResource,因為可以手動定義每個路由,這樣可以對每個路由有更細緻且完整的控制。
use App\Http\Controllers\UserController;
Route::get('users', [UserController::class, 'index']); // 列出所有使用者
Route::post('users', [UserController::class, 'store']); // 建立新使用者
Route::get('users/{id}', [UserController::class, 'show']); // 顯示特定使用者
Route::put('users/{id}', [UserController::class, 'update']); // 更新使用者資料
Route::delete('users/{id}', [UserController::class, 'destroy']); // 刪除使用者
這樣,我們就手動定義了每一個路由,並指定了對應的控制器方法。
為了讓路由更加結構化,我們可以使用 Route::group 來組織路由。
Route::prefix('users')->group(function () {
Route::get('/', [UserController::class, 'index']);
Route::post('/', [UserController::class, 'store']);
Route::get('/{id}', [UserController::class, 'show']);
Route::put('/{id}', [UserController::class, 'update']);
Route::delete('/{id}', [UserController::class, 'destroy']);
});
透過 prefix,我們將所有的使用者相關路由都歸類在 /users 路徑下。
為了方便在程式碼中引用路由,我們可以為路由命名。
Route::get('users', [UserController::class, 'index'])->name('users.index');
這樣,我們就可以在程式碼中使用 route('users.index') 來取得路由的 URL。
我們可以在路由上指定中介層,增加額外的功能,如身份驗證、日誌記錄等。
Route::middleware('auth:sanctum')->group(function () {
// 受保護的路由
Route::get('bank-accounts', [BankAccountController::class, 'index']);
// 其他需要保護的路由
});
我們可以為路由參數設定約束,確保請求的參數符合預期。
Route::get('users/{id}', [UserController::class, 'show'])
->where('id', '[0-9]+');
這表示 {id} 必須是數字,否則會回傳 404 錯誤。
按照同樣的方式,我們可以為其他資源如 BankAccount、Category 和 Transaction 定義路由。
use App\Http\Controllers\BankAccountController;
Route::prefix('bank-accounts')->group(function () {
Route::get('/', [BankAccountController::class, 'index']);
Route::post('/', [BankAccountController::class, 'store']);
Route::get('/{id}', [BankAccountController::class, 'show']);
Route::put('/{id}', [BankAccountController::class, 'update']);
Route::delete('/{id}', [BankAccountController::class, 'destroy']);
});
use App\Http\Controllers\CategoryController;
Route::prefix('categories')->group(function () {
Route::get('/', [CategoryController::class, 'index']);
Route::post('/', [CategoryController::class, 'store']);
Route::get('/{id}', [CategoryController::class, 'show']);
Route::put('/{id}', [CategoryController::class, 'update']);
Route::delete('/{id}', [CategoryController::class, 'destroy']);
});
use App\Http\Controllers\TransactionController;
Route::prefix('transactions')->group(function () {
Route::get('/', [TransactionController::class, 'index']);
Route::post('/', [TransactionController::class, 'store']);
Route::get('/{id}', [TransactionController::class, 'show']);
Route::put('/{id}', [TransactionController::class, 'update']);
Route::delete('/{id}', [TransactionController::class, 'destroy']);
});
有時,我們需要定義子資源的路由。例如,取得特定使用者的所有銀行帳戶。
Route::get('users/{userId}/bank-accounts', [BankAccountController::class, 'getByUser']);
為了避免在每個路由中都指定完整的控制器名稱,可以使用命名空間。
Route::namespace('App\Http\Controllers')->group(function () {
// 在這裡定義的路由都在指定的命名空間下
});
如果你想要使用 Laravel 提供的資源控制器,但又不想使用 apiResource,可以使用 Route::resource,然後在路由選項中指定 only 或 except。
Route::resource('users', UserController::class)->only([
'index', 'show', 'store', 'update', 'destroy'
]);
執行以下指令,可以查看所有已定義的路由,確認路由是否正確。
php artisan route:list
使用 Postman 或其他 API 測試工具,發送請求到定義的路由,檢查是否得到預期的response。
在開發過程中,良好的路由設計能夠大大提高開發效率和程式碼的可維護性。手動定義路由雖然可能看起來繁瑣,但它給予我們更高的靈活性。我曾在一個專案中,需要對不同的路由應用不同的中介層和參數約束,手動定義路由讓我能夠精細地控制每個路由的行為。
透過本篇文章,我們學習了如何在 Laravel 中手動定義路由,並使用群組、前綴和中介層來組織路由。我們了解了:
個人經驗分享:掌握路由的各種用法,能夠讓你的專案架構更加清晰,程式碼也更易於維護。
在理解了路由的設定後,下一篇我們將深入探討 控制器(Controller) 的實作。我們會學習如何在控制器中處理請求、進行資料驗證,以及如何與模型互動。