iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
Software Development

Laravel 新手初見 API系列 第 7

Day07-Response 最重要的是整整齊齊-API Resources

大家好~
延續昨天說的話題,
如果我們想修改 API 回傳的格式,
還要在每個 function 中個別修改那豈不是很麻煩嗎?
而今天要來實作的 API Resources 就能解決上述的問題囉~

建立 API Resources

首先先來建立我們 Message 的 Resource 吧!

php artisan make:resource Message
php artisan make:resource MessageCollection

輸入上面兩個指令後,
我們會得到兩個 Resource ,
為什麼要有兩個呢?
簡單來說,
以上面建立的兩個 Resource 為例:

  • app/Http/Resources/Message.php
    是轉換單個 Model 的 Resource,extends 了 JsonResource。
  • app/Http/Resources/MessageCollection.php
    是轉換 Collection 的 Resource,extends 了 ResourceCollection。

兩個 Resource 負責的工作不太一樣喔!

在建立 Resource 時帶上 --collection 參數,
或是使用 Collection 當作名稱結尾,
都能夠建立 extends 了 ResourceCollection 的 Resource 喔~

實作 API Resources

app/Http/Resources/Message.php
public function toArray($request)
{
    return [
        'id' => $this->id,
        'title' => $this->title,
        'content' => $this->content,
        'updated_at' => $this->updated_at,
        'user' => User::make($this->whenLoaded('user')),
    ];
}

這樣簡單 Resource 就完成囉!
簡單介紹一下,
基本格式大概是這樣的規則:

return [
    '自定義 Key 值' => $this->Model屬性名稱,
];

那該如何用他轉換我們想回傳的資料呢?

首先先在要使用 Resource 的 Controller 內 use 他們吧。

use App\Http\Resources\Message as MessageResource;
use App\Http\Resources\MessageCollection;

以檢索單一筆留言為例,
我們原本是:

public function show($messageId)
{
    $message = Message::with('user')->findOrFail($messageId);

    return response($message, Response::HTTP_OK);
}

現在改成:

public function show($messageId)
{
    $message = Message::with('user')->findOrFail($messageId);

    return response(MessageResource::make($message), Response::HTTP_OK);
}

上面的例子是用當資料型態為 Model 時為例子,
那如果資料型態是 Collection 呢?

這是我們原本的查詢所有留言功能 return response 的方式:

public function index()
{
    $messages = Message::with('user')->get();

    return response($messages, Response::HTTP_OK);
}

只要改成:

public function index()
{
    $messages = Message::with('user')->get();

    // 方法 1.
    return response(MessageCollection::make($messages), Response::HTTP_OK);
    // 方法 2.
    return response(MessageResource::collection($messages), Response::HTTP_OK);
}

方法1與方法2都可以回傳資料型態為 Collection 的資料喔!

成果預覽:

show( )

index( )

Resource 提供許多有趣且實用的用法,
本次範例無法一一介紹到,
像上方用到的 whenLoaded() 會判斷資料有沒有加載關聯,
若沒有加載關聯,
該 Key 就不會回傳。
這樣也可以避免查詢時發生「N+1」問題喔~

下圖就是沒加載 user 關聯時的回傳結果,
可以看到回傳格式中沒有出現 user 的 key。

小結:

  1. 不一定要建立兩種 Resource,使用 Resource::collection( ) 也可以處理 Collection 的資料。
  2. 在使用的時候要注意好我們的資料型態是 Model 還是 Collection,不然會報錯喔。

那麼今天就先這樣啦!
大家明天見~
若文章有任何問題,
還請大家不吝賜教!

參考資料:


上一篇
Day06-CRUD API 實作(六)CRUD 實作(下)
下一篇
Day08-為了讓表單資料不要太過自大,給予其正確的絕望-Validation(I)
系列文
Laravel 新手初見 API30

尚未有邦友留言

立即登入留言