logo api platform

API Platform et les DataTransformer

Spread the love

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

Laisser un commentaire

%d blogueurs aiment cette page :