API Resource

Voir la vidéo
Description Sommaire

Dans ce chapitre on va évoquer la partie API de Laravel et on va voir comment gérer la sérialisation de nos modèles en JSON. Par défaut, lorsque l'on retourne directement un modèle dans un controller, Laravel va le convertir en tableau puis en JSON en exposant l'ensemble des attributs du modèle. Dans un cas réel on veut pouvoir sélectionner les champs à exposer via notre API et c'est là que le système de Resource intervient.

Comme d'habitude pour créer ce type de classe on va passer par une commande artisan.

php artisan make:resource PostResource

Ensuite on peut utiliser cette classe dans le controller lorsqu'on souhaite renvoyer les informations d'un modèle.

function show (Post $post) {
    return new PostResource($post);
}

Et aussi utiliser la méthode statique dans le cas d'une collection

function index () {
    return PostResource::collection(Post::limit(5)->get());  
}

Dans la resource il est possible de définir les champs à renvoyer gràce à la méthode toArray().

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->name,
            'slug' => $this->email,
            'published_at' => $this->published_at
        ];
    }
}

On notera que l'on peut accéder au propriété du modèle en utilisant la variable $this directement. La class Resource va automatiquement faire proxy et utiliser les propriétés et les méthodes du modèle. Si vous n'êtes pas à l'aise avec cette "magie" vous pouvez aussi accéder à la propriété $resource qui contiendra le modèle courant.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @property App\Models\Post $resource
 **/
class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->resource->id,
            'title' => $this->resource->name,
            'slug' => $this->resource->email,
            'published_at' => $this->resource->published_at
        ];
    }
}

Il est aussi possible de conditionner la présence d'une propriété à l'aide de divers méthodes comme when().

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @property App\Models\Post $resource
 **/
class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->resource->id,
            'title' => $this->resource->name,
            'slug' => $this->resource->email,
            'published_at' => $this->resource->published_at,
            'created_at' => $this->when($request->user()->isAdmin(), $this->resource->created_at)
        ];
    }
}

Vous avez aussi la possibilité d'inclure des éléments provenant d'une relation, et de ne l'inclure que si la relation a été préchargée.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

/**
 * @property App\Models\Post $resource
 **/
class PostResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->resource->id,
            'title' => $this->resource->name,
            'slug' => $this->resource->email,
            'tags' => TagResource::collection($this->whenLoaded('tags')),
            'published_at' => $this->resource->published_at,
        ];
    }
}

Collection

En plus des resources classiques vous pouvez aussi générer des resources qui vont servir à représenter des collections.

php artisan make:resource PostCollection
# si le nom de la classe ne termine pas par "Collection"
php artisan make:resource PostResource --collection

Cette classe possède aussi une méthode toArray() qui permet de spécifier le retour. Dans cette méthode vous pouvez utiliser la propriété $collection pour récupérer la collection d'élément.

<?php
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class PostCollection extends ResourceCollection
{

    public function toArray($request)
    {
        return [
            'data' => $this->collection,
            'meta' => [
                'base' => 'https://grafikart.fr/',
            ],
        ];
    }
}
Publié
Technologies utilisées
Auteur :
Grafikart
Partager