REST是種軟體建構風格,常見限制如下:
而這些拘限,讓API架構具備高性能、可擴展、通用性、簡潔、可修改、可擴展等特性。
在兩天前的文章有提到如何去create新增一筆資料,這篇會繼續把read、update、delete的部分提完。
預設作法
關於讀取資料的部分,預設有兩個action
Http Verb | URI | Action |
---|---|---|
GET | /userWater | index |
GET | /userWater/{userWater_id} | show |
如果不做任何額外設定的話,index預設要列出所有資料,show則依據index裡頭資料回傳的id,提供該id對應的內容
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return response()->json(['success' => true , 'message' =>"" , 'data'=>userWater::all() ],200);
}
/**
* Display the specified resource.
*
* @param \App\userWater $userWater
* @return \Illuminate\Http\Response
*/
public function show(userWater $userWater)
{
return response()->json(['success' => true , 'message' =>"" , 'data'=>$userWater ],200);
}
個人習慣
預設方法沒有針對單一用戶提供resource的action,因此個人會另外建立一個透過user id取得個人資訊的action,不會直接覆蓋預設的。
public function waterUser($id)
{
$id = intval($id);
$userP = userWater::where('user_id','=',$id)->get();
if ( $userP ){
return response()->json(['success' => true , 'message' =>"" , 'data'=>$userP ],200);
} else{
return response()->json(['success' => false, 'message' =>"user id error" , 'data'=> null ],400);
}
}
Http Verb | URI | Action |
---|---|---|
GET | /water/{user_id} | waterUser |
對應的URI如上,但也有些建議可以把URI寫成 「 /{user_id}/userWater/ 」的更易理解的形式。
預設作法
更新時,要知道每次請求要更新哪些欄位。
以底下的code為例,更新欄位的內容可能是$dietColumn裏6個參數之一,或是6種參數的排列組合。因此用 $request->filled($value))
判斷有無傳入數值,再更新欄位寫入資料庫。
public static $dietColumn = ['fruits', 'vegetables', 'grains', 'nuts', 'proteins', 'dairy'];
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\userDiet $userDiet
* @return \Illuminate\Http\Response
*/
public function update(Request $request, userDiet $userDiet)
{
foreach (self::$dietColumn as $value) {
if ($request->filled($value)) {
$userDiet->$value = $request->$value;
}
$userDiet->save();
}
if ($userDiet == true) {
return response()->json(['success' => true, 'message' => "update success", 'data' => null], 200);
} else {
return response()->json(['success' => false, 'message' => "update error", 'data' => null], 400);
}
}
postman調整
如果body使用form-data,會無法使用put。
解法可以參考這篇,body 加欄位、方法改為post,router還是寫put不用額外調整。
預設作法
直接輸入 $userWater 對應的id,即可刪除該筆資料
Http Verb | URI | Action |
---|---|---|
DELETE | /userWater/{userWater_id} | destroy |
/**
* Remove the specified resource from storage.
*
* @param \App\userWater $userWater
* @return \Illuminate\Http\Response
*/
public function destroy(userWater $userWater)
{
$userWater->delete();
return response()->json(['success' => true , 'message' =>"delete success" , 'data'=>null ],200);
}
這系列的RESTful API作法,都建立於Laravel有個 Resource Controllers 的概念,讓我們可以透過以下action方式,只要知道resource model 的id (userWater的id),就可read/update/delete resource。
public function show(userWater $userWater)
public function update(Request $request, userWater $userWater)
public function destroy(userWater $userWater)
但給錯$userWater id 時,要怎麼提醒錯誤資訊呢?
可在「 app/Exceptions/Handler.php」的 render() ,設定 ModelNotFoundException的處理方式,讓Laravel幫忙抓到 resource model 的 id異常(不存在、軟刪除、錯誤id格式)等例外狀態。
/**
* Render an exception into an HTTP response.
*
*/
public function render($request, Throwable $exception)
{
if ($exception instanceof ModelNotFoundException) {
return response()->json(['success' => false, 'message' =>"input id error" , 'data'=> null ],400);
}
return parent::render($request, $exception);
}
參考資料
https://restfulapi.net/rest-architectural-constraints/
https://ihower.tw/blog/archives/1542
https://stackoverflow.com/questions/51302049/could-not-submit-form-data-through-postman-put-request
https://laravel.com/docs/8.x/controllers#resource-controllers
https://learnku.com/docs/laravel/7.x/controllers/7461#resource-controllers