logo api platform

API Platform et les DataTransformer

Parfois la représentation d’une ressource est différente entre l’input et l’output de l’API.
Prenons comme exemple une ressource person : notre API serait capable de lire une carte d’identité. Nous aurions le document en entrée et toutes les informations du document en sortie.
Dans ces conditions, l’utilisation d’un DataTransformer nous sera d’une grande utilité, car dans notre base de données, c’est bien une personne qui sera stockée.

Le principe

DataTransformer API Platform
Source API Platform

Lors de la serialization et de la deserialization, le serializer va chercher un transfomer qui supporte notre entité ou notre DTO. Avec 2-3 annotations et la magie de Symfony… Voilà un nouvel objet !

Le DataTransformer

La mise en place est relativement simple. Il faudra implémenter DataTransformerInterface pour chaque transformer et ajouter une annotation sur l’entité.

<?php

namespace App\Dto;

use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
use App\Entity\Person;
use Extenal\IDReader;

class PersonInputDataTransformer implements DataTransformerInterface
{
    private IDReader $idReader;

    public function __construct(IDReader $idReader)
    {
        $this->idReader = $idReader;
    }

    public function transform($object, string $to, array $context = [])
    {
        $personID = $this->idReader->read($object->document);

        return  (new Personne())
         ->setFirstName($personID->firstName)
         ->setLastName($personID->lastName);
    }

    public function supportsTransformation($data, string $to, array $context = []): bool
    {
        if ($data instanceof Person) {
            return false;
        }

        return Person::class === $to && null !== ($context['input']['class'] ?? null);
    }
}

<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use App\Dto\PersonInput;
use App\Dto\PersonOutpout;

/**
 * @ApiResource( input=PersonInput::class,    output=PersonOutpout::class )
 * @ORM\Entity()
 */
class Person
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /** @ORM\Column(type="string", length=255)   */
    private $firstName;

    /** @ORM\Column(type="string", length=255) */
    private $lastName;

    public function getId(): ?int
    {
        return $this->id;
    }
    /*
     ... all getter and setter
    */
}

Aller plus loin

Il est possible d’avoir un input et un ouput par opération, ce qui laisse beaucoup de possibilités.
Une fois la CNI upload, on peut laisser la possibilité d’éditer les informations présentes.

/**
 * @ApiResource(
 *     collectionOperations={
 *         "create"={
 *             "method"="POST",
 *             "input"=CreatePerson::class,
 *             "output"=PersonOutput::class
 *         }
 *     },
 *     itemOperations={
 *         "update"={
 *             "method"="PUT",
 *             "input"=UpdatePerson::class,
 *             "output"=PersonOutput::class
 *         }
 *     }
 * )
 */
final class Person
{
}

Super ! Maintenant il ne vous reste plus qu’à créer DataTransformer.
Merci API platform ?

chevron_left
chevron_right

Participer à la discussion

comment 1 commentaire
  • Blériot TIANA

    C’est instructif , super et merci beaucoup!

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Commentaire
Nom
E-mail
Site