10. Utiliser des groupes

Pourquoi ?

Commençons déjà par répondre à l'intérêt de la mise en place de groupe de sérialisation.

Si je reprends notre application à l'heure actuelle : 

- notre page d'accueil nous liste nos entités avec toutes nos informations

- notre page phone nous liste toutes les informations d'un téléphone basé sur l'id passé en paramètre.

Pour optimiser le rendu de notre page d'accueil, on va se contenter de récupérer non pas toutes les informations liées à notre entité, mais uniquement son identifiant, son nom et son prix.

Lorsqu'on voudra avoir plus d'informations sur une ressource en particulier, on pourra obtenir ces informations en allant sur la page de cette ressource.

On aura maintenant : 

- la page d'accueil qui liste nos entités avec les infos essentielles (id, nom et prix)

- la page phone, qui affiche toutes les informations liées à une ressource.

 

Mettons en place nos groupes dès maintenant. 😉

 

Ajoutons nos groupes

On va créer ici deux groupes : 

- list : qui sera le groupe pour afficher les éléments sur notre page de phones

- show : qui affichera les informations lors de l'accès à la ressource unique via son id.

 

Commençons par modifier notre entité : 

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;

/**
 * @ORM\Entity(repositoryClass="App\Repository\PhoneRepository")
 */
class Phone
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @Groups({"list", "show"})
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Groups({"list", "show"})
     */
    private $name;

    /**
     * @ORM\Column(type="integer")
     * @Groups({"list", "show"})
     */
    private $price;

    /**
     * @ORM\Column(type="string", length=255)
     * @Groups({"show"})
     */
    private $color;

    /**
     * @ORM\Column(type="text")
     * @Groups({"show"})
     */
    private $description;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getPrice(): ?int
    {
        return $this->price;
    }

    public function setPrice(int $price): self
    {
        $this->price = $price;

        return $this;
    }

    public function getColor(): ?string
    {
        return $this->color;
    }

    public function setColor(string $color): self
    {
        $this->color = $color;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(string $description): self
    {
        $this->description = $description;

        return $this;
    }
}

 

Modifions maintenant notre Contrôleur : 

<?php

namespace App\Controller;

use App\Entity\Phone;
use App\Repository\PhoneRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface;

/**
 * @Route("/api/phones")
 */
class PhoneController extends AbstractController
{
    /**
     * @Route("/{id}", name="show_phone", methods={"GET"})
     */
    public function show(Phone $phone, PhoneRepository $phoneRepository, SerializerInterface $serializer)
    {
        $phone = $phoneRepository->find($phone->getId());
        $data = $serializer->serialize($phone, 'json', [
            'groups' => ['show']
        ]);
        return new Response($data, 200, [
            'Content-Type' => 'application/json'
        ]);
    }

    /**
     * @Route("/{page<\d+>?1}", name="list_phone", methods={"GET"})
     */
    public function index(Request $request, PhoneRepository $phoneRepository, SerializerInterface $serializer)
    {
        $page = $request->query->get('page');
        if(is_null($page) || $page < 1) {
            $page = 1;
        }
        $phones = $phoneRepository->findAllPhones($page, getenv('LIMIT'));
        $data = $serializer->serialize($phones, 'json', [
            'groups' => ['list']
        ]);
        return new Response($data, 200, [
            'Content-Type' => 'application/json'
        ]);
    }

}

 

Retournez sur Postman, accédez à l'URL http://localhost:8000/api/phones :


 

Essayez maintenant d'accéder à l'URL http://localhost:8000/api/phones/1


 

On récupère bien les bonnes informations, limitées sur la page qui liste les téléphones, pour gagner en performance, et détaillées sur une page qui liste une ressource en particulier.

Occupons-nous maintenant de corriger l'erreur qui s'affiche lorsqu'on accède à une ressource inconnue.