web-dev-qa-db-fra.com

Ressources de l'API Laravel 5.5 pour les collections (données autonomes)

Je me demandais s'il était possible de définir différentes données pour une ressource d'élément et une ressource de collection. 

Pour la collecte, je veux seulement envoyer ['id', 'title', 'slug'] mais la ressource item contiendra des détails supplémentaires ['id', 'title', 'slug', 'user', etc.]

Je veux réaliser quelque chose comme:

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 ne fonctionnera pas comme prévu car il utilise PageResource donc il en a besoin 

return [
            'data' => $this->collection,
       ];

Je pourrais dupliquer la ressource dans PageFullResource/PageListResource et PageFullResourceCollection/PageListResourceCollection mais j'essaie de trouver un meilleur moyen d'obtenir le même résultat.

8
Dorin Niscu

La classe Resource a une méthode de collection dessus. Vous pouvez renvoyer cela comme entrée de paramètre à votre ResourceCollection, puis spécifier vos transformations sur la collection.

Manette:

class PageController extends Controller
{
    public function index()
    {
        return new PageResourceCollection(PageResource::collection(Page::all()));
    }

    public function show(Page $page)
    {
        return new PageResource($page);
    }
}

Ressources:

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,
                ];
            }),
        ];
    }
}
17
Jeff Puckett

Si vous souhaitez que les champs de réponse aient la même valeur dans la ressource et la collection, vous pouvez réutiliser la ressource dans la collection.

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);
    }
}
0
cyberfly

La réponse acceptée fonctionne si vous n'êtes pas intéressé par l'utilisation de liens et de métadonnées. Si vous voulez, retournez simplement:

return new PageResourceCollection(Page::paginate(10));

dans votre contrôleur. Vous devez également vous efforcer de charger d'autres relations dépendantes avant de passer à la collection de ressources.

0
Wale