Ich habe mich gefragt, ob es möglich ist, andere Daten für Elementressourcen und Sammelressourcen zu definieren.
Für die Sammlung möchte ich nur ['id', 'title', 'slug']
senden, aber die Artikelressource enthält zusätzliche Details ['id', 'title', 'slug', 'user', etc.]
.
Ich möchte etwas erreichen wie:
class PageResource extends Resource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
'user' => [
'id' => $this->user->id,
'name' => $this->user->name,
'email' => $this->user->email,
],
];
}
}
class PageResourceCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request
* @return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
];
}
}
PageResourceCollection funktioniert nicht wie erwartet, da es PageResource verwendet
return [
'data' => $this->collection,
];
Ich könnte die Ressource in PageFullResource
/PageListResource
und PageFullResourceCollection
/PageListResourceCollection
kopieren, aber ich versuche, einen besseren Weg zu finden, um dasselbe Ergebnis zu erzielen.
Die Ressourcenklasse verfügt über eine Erfassungsmethode. Sie können dies als Parametereingabe an Ihre ResourceCollection zurückgeben und dann Ihre Transformationen für die Auflistung angeben.
Regler:
class PageController extends Controller
{
public function index()
{
return new PageResourceCollection(PageResource::collection(Page::all()));
}
public function show(Page $page)
{
return new PageResource($page);
}
}
Ressourcen:
class PageResource extends Resource
{
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
'user' => [
'id' => $this->user->id,
'name' => $this->user->name,
'email' => $this->user->email,
],
];
}
}
class PageResourceCollection extends ResourceCollection
{
public function toArray($request)
{
return [
'data' => $this->collection->transform(function($page){
return [
'id' => $page->id,
'title' => $page->title,
'slug' => $page->slug,
];
}),
];
}
}
Wenn die Antwortfelder in Ressource und Sammlung denselben Wert haben sollen, können Sie die Ressource in der Sammlung wiederverwenden
PersonResource.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\Resource;
class PersonResource extends Resource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
// return parent::toArray($request);
return [
'id' => $this->id,
'person_type' => $this->person_type,
'first_name' => $this->first_name,
'last_name' => $this->last_name,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at,
];
}
}
PersonCollection.php
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class PersonCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection
*/
public function toArray($request)
{
// return parent::toArray($request);
return PersonResource::collection($this->collection);
}
}
Die akzeptierte Antwort funktioniert, wenn Sie nicht daran interessiert sind, Links und Metadaten zu verwenden. Wenn Sie möchten, kehren Sie einfach zurück:
return new PageResourceCollection(Page::paginate(10));
in Ihrem Controller. Sie sollten auch andere abhängige Beziehungen laden, bevor Sie zur Ressourcensammlung wechseln.