--- tags: PHP / Laravel / Lumen --- # Laravel 建立 RESTful API ### 前置作業 由於本篇將使用 API 的 Auth 驗證,所以請「**務必**」參考[Laravel JWT](https://hackmd.io/s/SkqRnxqIM) 請先備齊[Postman](https://www.getpostman.com/) (用來測試API) ---- ## API? API (Application Programming Interface,應用程式介面),以web而言,簡單來說就是**後端**與**前端**溝通的**橋樑**,而這裡指的前端,不單只是WEB,也包含了Mobile APP和其他服務。而API扮演了特定功能的窗口,使前端能藉此訪問後端,執行特定功能。 ## Practice 今天我們一樣使用文章的CRUD作為開發的示範,而差異在於API改為回傳JSON Response,而不做任何頁面渲染 ### 1. 建立controller ``` php artisan make:controller api/PostController --api ``` * 在 Laravel 5.6 以後,建 controller 的指令多了「--api」的參數可以使用,它能夠為你省略「create」及「edit」的方法 ### 2. routes\api.php 新增路由 ```php Route::middleware('auth:api')->group(function () { Route::apiResource('post', 'api\PostController'); }); ``` * web與api各自使用不同的中介層及路由前綴,請見app\Providers\RouteServiceProvider.php ### 3. app\Http\Controllers\api\PostController.php,注入repository ```php <?php namespace App\Http\Controllers\api; use App\Http\Controllers\Controller; use App\Repositories\PostRepository; class PostController extends Controller { protected $postRepo; public function __construct(PostRepository $postRepo) { $this->postRepo = $postRepo; } public function index() { return response()->json(['status' => 0, 'posts' => $this->postRepo->index()]); } public function store() { $post = $this->postRepo->create(request()->only('title', 'content')); if (!$post) { return response()->json(['status' => 1]); } return response()->json(['status' => 0, 'post' => $post]); } public function show($id) { $post = $this->postRepo->find($id); if (!$post) { return response()->json(['status' => 1, 'message' => 'Post not found'], 404); } return response()->json(['status' => 0, 'post' => $post]); } public function update($id) { $result = $this->postRepo->update($id, request()->only('title', 'content')); if (!$result) { return response()->json(['status' => 1, 'message' => 'Post not found'], 404); } return response()->json(['status' => 0]); } public function destroy($id) { $result = $this->postRepo->delete($id); if (!$result) { return response()->json(['status' => 1, 'message' => 'Post not found'], 404); } return response()->json(['status' => 0]); } } ``` ### 4. 手動建立 app\Repositories\PostRepository.php ```php <?php namespace App\Repositories; use App\Entities\Post; class PostRepository { public function index() { return Post::get(); } public function find($id) { return Post::find($id); } public function create(array $data) { return auth()->user()->posts()->create($data); } public function update($id, array $data) { $post = Post::find($id); return $post ? $post->update($data) : false; } public function delete($id) { return Post::destroy($id); } } ``` 接著用Postman來實測一下api吧! #### API參數對照表 | URI | description | HTTP Method | Header | Body | | -------- | -------- | -------- | -------- |-------- | | api/post | 文章列表 | GET | Authorization: bearer **Token** <br >Accept: application/json | | | api/post/{id} | 特定文章 | GET | Authorization: bearer **Token** <br >Accept: application/json | | | api/post | 新增文章 | POST | Authorization: bearer **Token** <br >Accept: application/json |title<br>content | | api/post/{id} | 更新文章 | PUT/PATCH | Authorization: bearer **Token** <br >Accept: application/json |title<br>content | | api/post/{id} | 刪除文章 | DELETE | Authorization: bearer **Token** <br >Accept: application/json | | ※使用form-data傳送「GET、POST以外」的請求時,會發生資料未被更新的問題,因為HTML的form僅支援GET、POST,而更新文章要求使用的PUT/PATCH是沒有被支援的,所以各位可以嘗試以下方法: 1. 將 Method 改為POST,並於Body的form-data中加上一組key為「_method」、value為「put」的參數 2. 使用 x-www-form-urlencoded 3. 使用 raw 的 JSON(application/json),透過JSON格式傳輸 ※ Header 中的 token,為登入後所取得的憑證,用於讓後端判斷你的身分是否合法(是否登入) ※ Accept:application/json 用於指定 API 的 Response 為 JSON 格式 (接收token過期或憑證非法的Response)