📘

Laravelでページネーション付きのレスポンスデータの指定を行う

2023/03/04に公開

ページネーションがついている場合にレスポンスデータってどうやって絞るの、クエリでselectするしかないの?と考えて色々試していましたが、一番きれいにできたので共有します。

ユーザーデータの個々のデータを返却する形式を決める

app/Http/Resources/UserResource.php を作成し、ユーザー情報の返却したいものだけを選ぶ。
これは今回はidとnameとemail, role_format(権限)のみにしておきます。

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'role_format' => $this->role_format
        ];
    }
}

これで、ユーザー一人ひとりのデータのフォーマットはできました。

たとえば、このような文法で、一つのデータのフォーマットを行うイメージです。

new UserResource(User::find(1));

しかし、子では一つのデータは返却形式を決められますが、
allpaginate などで手に入れた一覧データのレスポンス形式を決めることはできません。

ユーザー情報を全体を返却するUserCollectionを作成する

all や paginateなどのデータの返却のデータレスポンス形式を加工するために、UserCollectionを作成します。 (app/Http/Resources/UserCollection.php

UserContorllerでは、foreachで先ほど作成したUserResourceで一つ一つのデータを処理します。

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class UserCollection extends ResourceCollection
{
    /**
     * Transform the resource collection into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
     */
    public function toArray($request)
    {
        /** @var Illuminate\Support\Collection<\App\Models\User> */
        $users = $this->collection;

        $userData = collect();

        foreach ($users as $user) {
            $userData->push(new UserResource($user));
        }

        return $userData;
    }
}

レスポンスの際にあと一手間

return response(new UserResource(User::paginate(20)));

このまま通常通りにreturnすると、ページネーションの情報が一切消えています。
なぜ!

というわけで調べに調べて解決策見つかりました。こちらです。

$users = new UserResource(User::paginate(20));
return response($users->response()->getData(true));

こちらの->response()->getData(true) という部分が大活躍です。

誰かのお役に立てると幸いです。

Discussion