API Rest & Symfony : les débuts - SimplonReunion/developpeur-web GitHub Wiki
Nous allons mettre en place une min api basique avec Symfony.
La base de l'exercice sera l'exo repo.
Nous ne prendrons pas en compte la gestion des utilisateurs et des droits d'accès.
On va commencer par retourner la liste des clients des gites sous la forme Json.
Jusqu'à maintenant, on retournait une vue : un template twig. Cette vue est ni plus ni moins qu'une réponse de type html. Avec l'api on va renvoyer une réponse de type Json plutôt. C'est le front-end qui s'occupera de la mise en forme en se basant sur ce Json.
Pour tester nos urls nous allons utiliser un système qui permet juste d'envoyer des requêtes HTTP à notre application et d'afficher les réponses sans avoir besoin à développer une interface front-end. Il y a plusieurs façons de le faire. Nous allons opter pour l'extension Chrome Postman, assez simple à utiliser.
Le controller
Lister
Nous allons créer un nouveau controller qu'on appellera RestClientController.php
qui se trouvera dans le bundle de RepoPlaygroundBundle
.
Dans ce nouveau controller, on va définir une action qui a pour route '/api/clients' et qui va retourner la liste des clients des gites sous format Json. Cette route doit être accessible uniquement par en méthode GET
.
Pour récupérer les clients,on peut reprendre ce qu'on a déjà fait. La seule chose qui va changer c'est la fin de l'action. Nous n'allons plus retourner une vue mais plutôt un objet JsonResponse
, Symfony\Component\HttpFoundation\JsonResponse
pour un être précis.
Ci dessous la fameuse action :
/**
* Lister tous les clients.
*
* @Route("/clients", name="api_clients")
* @Method("GET")
*/
public function getClientsAction()
{
$em = $this->getDoctrine()->getManager();
$clients = $em->getRepository('SimplonReunionRepoPlaygroundBundle:Client')->findAll();
//retourne la réponse Json
return new JsonResponse(json_encode($clients));
}
Si on teste, on aura un Json sans données à l'intérieur. C'est parce que JsonResponse ne sait pas convertir des objets en Json.
Nou allons devoir passer par un convertisseur qui va le faire pour nous. l'un des plus utilisés est JMSSerializerBundle. On l'installe en suivant les instructions de la documentation.
On va maintenant modifier notre code pour ajouter le serializer:
/**
* Lister tous les clients
*
* @Route("/clients", name="api_clients")
* @Method("GET")
*/
public function getClientsAction()
{
$em = $this->getDoctrine()->getManager();
$clients = $em->getRepository('SimplonReunionRepoPlaygroundBundle:Client')->findAll();
//Récupère le serializer (qui est un service)
$serializer = $this->get('jms_serializer');
//Converti les objets en Json
$serializedClients = $serializer->serialize($clients, 'json');
//retourne la réponse Json
return new JsonResponse($serializedClients,200,[],true);
}
Si on regarde la documentation du constructeur de JsonReponse
on voit qu'il s'attend à avoir les paramètres suivants :
- Les données
- Le statut de la réponse
- Un tableau pour ajouter des headers
- Si les données passées sont déjà en Json
Dans notre cas :
$serializedClents
correspond à nos données à envoyées- Tout s'est bien passé donc on veut retourner une réponse qui vaut
200
- On ne veut pas ajouter des headers supplémentaires donc on passe un tableau vide
$serializedClents
est déjà en json (merci le serializer) c'est pourquoi le dernier paramètre vauttrue
Et voilà maintenant on a la liste des clients sous forme Json.
Exercice
Faites de même pour les autres entités, Gite, Gestionnaire, Reservation, Chambre.
Créer
On sait comment lister des entités avec notre api. On va maintenant voir comment insérer des clients.
Comme pour la partie insertion, on va utiliser le format Json. Les données qui seront passées à notre api seront sous la forme Json :
{
"nom": "Luke",
"prenom": "Skywalker",
"email": "[email protected]"
}
Dans nos actions, nous avons l'habitude de fonctionner avec des forms. Comme les données sont du Json on va utiliser une autre technique pltuôt.
On va créer l'objet Client
directement à partir du Json ! On va le déserialisé, puis après une petite validation on va l'insérer dans notre base.
/**
* Créer un client. IMPORTANT : les données sont soumis sous forme json !
*
* @Route("/client", name="api_clients_new")
* @Method("POST")
*/
public function newAction(Request $request)
{
//Récupère le serializer
$serializer = $this->get('jms_serializer');
//Les variables sont passées en Json. Il faut alors les transformer en objet Client
/** @var $client Symfony\Component\Form\Form */
$client = $serializer->deserialize($request->getContent(),Client::class,'json');
//Faire une validation sur les données fournis par l'utilisateur
/** @var $validator Symfony\Component\Validator\Validator\ValidatorInterface */
$validator = $this->get('validator');
$errors = $validator->validate($client);
if (count($errors) <= 0) {
$em = $this->container->get('doctrine')->getManager();
$em->persist($client);
$em->flush();
//Convertir les objets en Json
$serializedClient = $serializer->serialize($client, 'json');
return new JsonResponse($serializedClient, 201, [], true);
}
return new JsonResponse("Error : form not valid", 400);
}
Il faut garder à l'esprit que cette façon de faire n'est pas très sécurisée. En effet on est vulnérable a des attaques de type CRSF
Exercice
Créer les actions pour permettre l'ajout des autres entités.
Aller plus loin
Il reste plus qu'à faire la suppression d'un élément et la mise à jour d'un élément. À vous de jouer.