---
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)