📘
Laravelでページネーション付きのレスポンスデータの指定を行う
ページネーションがついている場合にレスポンスデータってどうやって絞るの、クエリで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));
しかし、子では一つのデータは返却形式を決められますが、
all
や paginate
などで手に入れた一覧データのレスポンス形式を決めることはできません。
ユーザー情報を全体を返却する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