在介紹完 controller 之後,接著要為 API 綁定 URL 讓其他系統可以使用。今天會依照下面主題逐一介紹 Laravel Routing 設定。
所有的 API 對應的網址都會寫在 routes
底下的檔案中,我們可以依照需求分在不同檔案,但目前我們只依照 Laravel 基本的分類寫在 routes\api.php
。
所有的方法都是呼叫 \Illuminate\Support\Facades\Route
(以下簡稱 Route) 而來,如果 IDE 連結不到原始的類別,可以安裝 barryvdh/laravel-ide-helper 讓開發更簡便。
五個常用的 HTTP 方法 (GET
、POST
、PUT
、PATCH
和DELETE
),會是最終、也是最簡單綁定 URL 和 API 方法的功能。這五個方法,第一個參數是自訂義的 URL;第二個參數是閉包或是對應的 controller function (以下稱為 action)。
Route::get('v1/post/view', 'PostController@read');
Route::post('v1/post/create', 'PostController@create');
Route::put('v1/post/update', 'PostController@edit');
Route::patch('v1/post/update/title', 'PostController@editTitle');
Route::delete('v1/post/delete', function (Request $request) {
// ...
});
從上面的範例可以看到 get()
、post()
、put()
和patch()
,我們都是以設定對應 action 方式綁定;delete()
則是使用閉包的方法。如果有一些沒有太多商業邏輯或是極其簡單的資料,也可以直接在閉包裡面處理和回傳 response。
我們有時因應需求,會需要在 URL 中間帶上資料,但又不想使用 query string,此時
只要在 URL 中間以 {<變數名稱>}
設定即可。
// api.php:
Route::post('v1/post/{postId}/update', 'PostController@edit');
// PostController.php:
class PostController extends Controller
{
public function edit($postId, FormRequest $request)
{
// ...
例如上面的例子,當我們呼叫 http://.../v1/post/2764/update
時,首先會根據 api.php
的設定執行 PostController 的 edit 方法,同時會將「2764」帶入 $postId
中。只要參數名稱與 route 中設定的一樣,在 action 中的位置順序,不影響資料的帶入。
在一些狀況下,我們要讓參數具有預設值,如同上面的設定,並在變數名稱後面加上「?」 如: {<變數名稱>?}
即可。
// api.php:
Route::post('v1/post/eidt/{title?}', 'PostController@editTitle');
// PostController.php:
class PostController extends Controller
{
public function editTitle($title = "no title", FormRequest $request)
{
// ...
在動態變數中 Laravel 提供方便驗證變數是否合法的方式 where()
。第一個參數是變數名稱,第二個參數是驗證變數值的正則表示式;如果一個 URL 有多個變數需要驗證可以改用 array 的方式。
Route::post('v1/post/{postId}/update', 'PostController@edit')->where('postId', '[0-9]+');
從一開始五個常用的 HTTP 方法設定範例中我們可以看到每一個 URL 都有共同的部份 v1/post
,在 Laravel 中透過分組 (groups) 的寫法,進一步整合管理,減少重複撰寫相同的部份或是共同的設定。以下介紹幾個常用的分組方法,完整介紹請參考官網。
prefix
: 前缀是用來設定 URL 開始共同的部份,如上面 HTTP 方法的範例,我們可以改寫為:Route::prefix("v1/post")->group(function () {
Route::get('view', 'PostController@read');
Route::post('create', 'PostController@create');
Route::put('update', 'PostController@edit');
// ...
});
namespace
: 假若我們要綁定的 controller 不是在預設的 app/Http/Controller
裡面,而是有更進一步的分類,這時候可以設定 namespace()
方便管理。例如我們將 controller 分在 app/Http/Controller/Admin
和 app/Http/Controller/User
兩個資料夾,我們就可以設計如:Route::namespace('Admin')->group(function () {
Route::get('v1/admin/manager/create', 'ManagerController@createManager');
Route::get('v1/admin/user/{id}/delete', 'ManagerController@delete');
// ...
});
middleware
: Middleware 是 Laravel 在進入 action 之前會先對 http request 進行過濾、檢查的地方,這部份我們會在明後天更進一步的說明。在 route 中,我們可以將有共同過濾或檢查機制管理在一起。Route::middleware('adminonly')->group(function () {
Route::get('v1/admin/manager/create', 'UserController@createManager');
Route::get('v1/admin/user/{id}/delete', 'UserController@delete');
// ...
});
所有在 api.php
設定的 routing,完整網址都是由 <domain 或是 IP>/api/....
組成。我們可以打開 app\Providers\RouteServiceProvider.php
,在 mapApiRoutes()
中客製化自己的設定,
protected function mapApiRoutes()
{
Route::prefix('api') // 可以改成自己的 prefix 或是移除,以下類推
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php')); // 這裡定義了要套用到哪一個設定檔
}
另外,我們在綁定了 URL 與 action 之後,我們可以使用postman這個很好用的發送 http request 工具,測試我們所寫的 API。
終於! 到目前為止我們可以用 Laravel 寫出完整的 API 服務,學習曲線個人認為滿舒服的,大家可以試試看! 明天我們將進一步地叫紹 Laravel Middelware 的部分,像上面說的,透過 middlewares 可以讓我們進到 action 之前就先檢查、過濾不合法的 request,例如,一般使用者的身分不得執行或是呼叫管理者的 API 等諸如此類的保護機制!
最近在學習Laravel 按照著大大步驟慢慢學習
想請問為什麼我得按照的程式碼輸入但是我的路由卻沒有出現五個呢?
是哪個地方出現問題還請指點一下
诶斗... 你上傳的圖片失效耶 XD
另外問一下,你是使用哪個版本的 Laravel (我猜是 8.0)?
在 Day02 裡面有提到當時候這篇是以 5.8 做教學的,金拍謝~ 不過有問題我可以找時間盡量幫看看新版的文件說明~
回到主題,在 8.0 的文件中,Route 的寫法改變了,主要是因為
RouteServiceProvider.php 裡的變數 $namespace
預設改為 null
(在之前版本預設會是 'App\Http\Controllers'
)。
所以解決方法:
Route::get('v1/post/view', [PostController::class, 'read']);
$namespace
賦值為 'App\Http\Controllers'