A Laravel APIリソース は、単一のリソースまたはコレクションのいずれかです。場合によっては、コントローラーからリソース/コレクションに追加のパラメーターを渡す必要があります。以下は、シングル/コレクションリソースとしてUser
を使用し、出力用にリソースに渡すカスタム_$Apple
_パラメーターを使用する問題を示す簡単な例です。問題は、最後のOutput (Collection)
で確認できます。以下では、fruit
の値について、正しいbanana
の値(他のすべてのユーザーが取得する)ではなく、最初のユーザーのApple
の誤った値を取得します。
UserResourceを使用したコントローラー(シングル)
_ $user = User::first();
return new UserResource($user, $Apple = true); // $Apple param passed
_
UserResource(コレクション)を持つコントローラー
_ $users = User::limit(3)->get();
return UserResource::collection($users, $Apple = true); // $Apple param passed
_
UserResource
_ <?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource {
private $Apple;
public function __construct($resource, $Apple = false) {
// Ensure we call the parent constructor
parent::__construct($resource);
$this->resource = $resource;
$this->Apple = $Apple; // $Apple param passed
}
public function toArray($request) {
return [
'id' => (int) $this->id,
'name' => $this->name,
'fruit' => $this->Apple ? 'Apple' : 'banana',
];
}
}
_
出力(シングル)
_ {
"data": {
"id": 1,
"name": "Peter",
"fruit": "Apple" // correct param!
}
}
_
出力(コレクション)
_ {
"data": [
{
"id": 1,
"name": "Peter",
"fruit": "banana" // INCORRECT param!
},
{
"id": 2,
"name": "Lois",
"fruit": "Apple" // correct param!
},
{
"id": 3,
"name": "Brian",
"fruit": "Apple" // correct param!
}
]
}
_
これは単なる例であり、任意のテーブルからの単一の値_read_at
_タイムスタンプなど、任意の量のランダムパラメーター(User
コレクションとは無関係ですが、出力ロジックに渡す必要がある)であることに注意してください一度渡して、出力前にリソースコレクションで何らかのロジック(ユーザータイムスタンプとの比較など)を実行するか、追加のロジック_if/else
_に渡されるその他のパラメーターを実行して、一般的にリソースファイルで実行し、コレクション。これをどのように行うことができますか?
次のアプローチは私のために働いた:
serResource
class UserResource extends Resource{
protected $foo;
public function foo($value){
$this->foo = $value;
return $this;
}
public function toArray($request){
return [
'id' => $this->id,
'name' => $this->name,
'foo' => $this->foo,
];
}
public static function collection($resource){
return new UserResourceCollection($resource);
}
}
serCollection
class UserResourceCollection extends ResourceCollection{
protected $foo;
public function foo($value){
$this->foo = $value;
return $this;
}
public function toArray($request){
return $this->collection->map(function(UserResource $resource) use($request){
return $resource->foo($this->foo)->toArray($request);
})->all();
// or use HigherOrderCollectionProxy
// return $this->collection->each->foo($this->foo)->map->toArray($request)->all()
// or simple
// $this->collection->each->foo($this->foo);
// return parent::toArray($request);
}
}
追加のパラメーターを渡す別の方法
(new UserResource($user))->foo('bar');
(new UserResourceCollection($user))->foo('bar');
UserResource::make($user)->foo('bar');
UserResourceCollection::make($users)->foo('bar');
UserResource::collection($users)->foo('bar');
Laravel 5.7で動作するように、 ウォンカの答え
UserResource
class UserResource extends Resource{
protected $foo;
public function foo($value){
$this->foo = $value;
return $this;
}
public function toArray($request){
return [
'id' => $this->id,
'name' => $this->name,
'foo' => $this->foo,
];
}
public static function collection($resource){
return new UserResourceCollection($resource, get_called_class());
}
}
UserCollection
class UserResourceCollection extends AnonymousResourceCollection {
protected $foo;
public function foo($value){
$this->foo = $value;
return $this;
}
public function toArray($request){
return $this->collection->map(function(UserResource $resource) use($request){
return $resource->foo($this->foo)->toArray($request);
})->all();
}
}
APIエンドポイントへの呼び出しの一部として、追加のパラメーターを渡すことができます。その後、UserResourceの(たとえば)$ requestオブジェクトを使用してパラメーターにアクセスできます。
たとえば、Webブラウザやaxiosなどのクライアントから次のようなものを使用してエンドポイントを呼び出す場合:
http://localhost:3000/api/users?apple=true
これにより、パラメーターApple trueの値がコントローラーで使用可能になります。他のアクションがなければ、UserResourceのtoArray($ request)でもアクセスできます。次のようにアクセスできます。
public function toArray($request) {
$isApple = $request->Apple;
return [
'id' => (int) $this->id,
'name' => $this->name,
'fruit' => $isApple ? 'Apple' : 'banana',
];
}