この記事はLaravelのResourcesに関する解説の記事です。
Resourcesとは
APIでEloquentモデルをJSON形式でレスポンスにする場合、キー名の変更や、created_atなど出力したくないフィールド、日時形式やフラグ値などの型変換、計算済の値の追加フィールドなど色々手を加えてから出力したい事が多いです。
これらの処理を簡単に、かつ共通のロジックにするのがResourcesです。
Resourceの作成
artisanコマンドにて作成します。
php artisan make:resource UserResource
Bashファイルはapp/Http/Resources
以下に作成されます。
Resourceの設定
出来上がったapp/Http/Resouces/UserResource.phpにはtoArrayメソッドがあり、これがJSONの返却値となります。
今回の例ではユーザー情報を取得するレスポンスなので、UserのEloquentをそのまま返すとメールアドレスやパスワードが混ざってしまって都合が悪いです。
そのため、指定したフィールドと、姓名を1フィールドにして返却するようにしています。
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
// return parent::toArray($request);
return [
'id' => $request->id,
'name' => $request->last_name . ' ' . $request->first_name,
'birthday' => date('Y-m-d', strtotime($request->birthday)),
];
}
}
PHPResourceを利用する
作成したUserResourceを利用してControllerから返却してみましょう。
UserResourceのインスタンス作成時の引数にユーザー情報を渡すと、出力時にtoArrayメソッドが呼ばれてJSON形式として出力されます。
<?php
namespace App\Http\Controllers;
use App\Services\UserService;
use App\Http\Resources\UserResource;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Auth;
class UserController extends Controller
{
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
/**
* get me
*/
public function getMe(Request $request)
{
if (Auth::check()) {
$user = Auth::user();
return new UserResource($user); // Userモデルのインスタンスを引数に渡す
}
return response()->json([], Response::HTTP_UNAUTHORIZED);
}
}
PHP上記のレスポンス例は以下となります。
{
"id": 12345,
"name": "Mike Davis",
"birthday": "1988-06-13"
}
JSONまとめ
Resourceを使うことにより、今回の例ではユーザー情報取得だけでしたが、ユーザー登録や変更の際のレスポンスで同様の内容を含ませる場合などに非常に便利な機能となります。
また、SNSなどを作る際、自分が見る用のUserResourceと、他人が見る用のUserResourceを別々に作ったりすると、見えてはいけないフィールドを出してしまったり、APIによってレスポンス内容が異なるようなことが防げたりもします。
APIを作成する際には便利なことも多いので、メンテナンス性も高くなるResourceの利用を検討してみると良いかと思います。
コメント