Tous droits réservés

Créez une API REST avec Symfony 3

Tout au long de ce cours, nous allons apprendre à mettre en œuvre les principes de REST pour concevoir et développer une API web avec Symfony 3.

REST s’est imposé dans le monde du web comme étant un paradigme approuvé et éprouvé pour concevoir des APIs (Application Programming Interface).

De grandes entreprises comme Github, Facebook (Graph) ou YouTube l’utilisent pour fournir des APIs largement utilisées pour accéder à leurs services.

À l’ère des sites web en Single Page Applications et des applications mobiles (Android, IOS ou encore Windows Phone), savoir développer une API est devenu incontournable.

Pourquoi utiliser REST plutôt qu’une autre technologie ou architecture ? Quels avantages cela peut-il nous apporter ? Comment développer une API REST avec Symfony ?

Tout au long de ce cours, nous allons apprendre à mettre en œuvre les principes de REST pour développer rapidement une application web fiable et extensible avec le framework Symfony et l’un de ses bundles phares FOSRestBundle.

Un tour d'horizon des concepts REST

  1. REST en quelques mots
  2. Pourquoi utiliser REST

Développement de l'API REST

  1. Notre environnement de développement

    1. Environnement technique

    2. Création d'un projet Symfony

  2. Premières interactions avec les ressources

    1. Lire une collection

    2. Lire une ressource

    3. Les codes de statut (status code) pour des messages plus expressifs

  3. FOSRestBundle et Symfony à la rescousse

    1. Installation de FOSRestBundle

    2. Routage avec FOSRestBundle

    3. Quid de l'attribut _format ?

    4. Gestion des réponses avec FOSRestBundle

    5. Pratiquons avec notre code

  4. Créer et supprimer des ressources

    1. Création d'une ressource

    2. Suppression d'une ressource

  5. Mettre à jour des ressources

    1. Mise à jour complète d'une ressource

    2. Mise à jour partielle d'une ressource

    3. Notre application vu selon le modèle de Richardson

  6. Relations entre ressources

    1. Hiérarchie entre ressources : la notion de sous-ressources

    2. Les groupes avec le sérialiseur de Symfony

    3. Mise à jour de la suppression d'une ressource

  7. TP : Le clou du spectacle - Proposer des suggestions aux utilisateurs

    1. Énoncé

    2. Détails de l'implémentation

    3. Travail préparatoire

    4. Proposer des suggestions aux utilisateurs

  8. REST à son paroxysme

    1. Supporter plusieurs formats de requêtes et de réponses

    2. L'Hypermédia

Amélioration de l'API REST

  1. Sécurisation de l'API 1/2

    1. Connexion et déconnexion avec une API

    2. Login et mot de passe pour les utilisateurs

    3. Création d'un token

  2. Sécurisation de l'API 2/2

    1. Exploitons le token grâce à Symfony

    2. Gestion des erreurs avec FOSRestBundle

    3. 401 ou 403, quand faut-il utiliser ces codes de statut ?

    4. Suppression d'un token ou la déconnexion

  3. Créer une ressource avec des relations

    1. Rappel de l'existant

    2. Création d'un lieu avec des tarifs

    3. Bonus : Une validation plus stricte

  4. Quand utiliser les query strings ?

    1. Pourquoi utiliser les query strings ?

    2. Gestion des query strings avec FOSRestBundle

    3. Paginer et Trier les réponses

  5. JMSSerializer : Une alternative au sérialiseur natif de Symfony

    1. Pourquoi utiliser JMSSerializerBundle ?

    2. Installation et configuration de JMSSerializerBundle

    3. Impact sur l'existant

  6. La documentation avec OpenAPI (Swagger RESTFul API)

    1. Qu'est-ce que OpenAPI ?

    2. Rédaction de la documentation

    3. Installer et utiliser Swagger UI

  7. Automatiser la documentation avec NelmioApiDocBundle

    1. Installation de NelmioApiDocBundle

    2. L'annotation ApiDoc

    3. Étendre NelmioApiDocBundle

    4. Le bac à sable

    5. Générer une documentation compatible OpenAPI

  8. FAQ

    1. Comment générer des pages HTML depuis l'application Symfony 3 ?

    2. Comment autoriser l'accès à certaines urls avec notre système de sécurité ?



Nous avons pu voir tout au long de ce cours que les contraintes REST permettent de mettre en place une API uniforme et facile à prendre en main. La mise en œuvre de ces contraintes offre un ensemble d’avantages et le framework Symfony dispose d’outils suffisamment matures pour aider dans les développements.

Ce cours bien qu’étant assez long n’aborde pas tous les concepts de REST ni toutes les fonctionnalités qu’apportent FOSRestBundle et les différents bundles utilisés. Son objectif est de présenter de manière succincte l’essentiel des notions à comprendre pour pouvoir développer une API RESTFul et l’améliorer en toute autonomie.

Le style d’architecture REST ne s’occupe pas des détails d’implémentations mais plutôt du rôle de chaque composant de notre application.

N’hésitez surtout pas enrichir l’API et à explorer les documentations officielles des différents outils abordés pour mieux cerner tout ce qu’ils peuvent vous apporter.

91 commentaires

Est-ce que je peut trouve ce tutorial au format pdf????

On a des problèmes avec la génération des PDF, ce qui fait qu’il n’y en a pas pour tous les tutoriels actuellement. Il y a du développement en cours pour corriger ça, désolé. :/

Au passage, merci BestCoder pour ce tutoriel qui me sera très utile si je me remets à faire du Symfony. :)

Bonsoir !

Un grand merci pour ce tuto ! Il semble plutôt complet et permet de faire son API rapidement ! Cependant, j’ai un souci : j’en suis à la "Sécurisation de l’API 1/2" et lorsque je créé un nouvel utilisateur, contrairement à ce qui est écrit, j’ai le mot de passe clair et hashé qui sont retournés…

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "email": "test@test.fr",
  "password": "$2y$12$gen0iesvyVvOt1eiu8GsReUyfnXXHPekLeNwB8VU.HRIwtcKM\/hB.",
  "plainPassword": "test",
  "nom": "Paul Eauchon",
  "id": 10,
  "roles": [],
  "salt": null,
  "username": "test@test.fr"
}

N’y aurait-il pas une configuration à faire et qui aurait été oubliée dans la rédaction du tuto ?

Merci par avance :)

N’y aurait-il pas une configuration à faire et qui aurait été oubliée dans la rédaction du tuto ?

Merci par avance :)

steff.helbling

Salut Steff, Effectivement il y a une configuration à effectuer la sérialisation pour l’entité user.

azeupaul

C’est bien ce que je pensais. Je débute sur Symfony et le peu de choses que j’ai trouvé ne m’ont pas aidé. Serait-il possible de me filer un petit coup de main ?

Normalement la sérialisation avec les groupes est abordée dans les chapitres précédents. Mais si elle est bien faite, la réponse ne devrait pas contenir le mot de passe.

Voir le chapitre : Relations entre ressources - Les groupes avec le sérialiseur de Symfony et même plus loin dans le chapitre Sécurisation de l’API 1/2, il y a un exemple concret.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# src/AppBundle/Resources/config/serialization.yml
# ...

AppBundle\Entity\User:
    attributes:
        id:
            groups: ['user', 'preference', 'auth-token']
        firstname:
            groups: ['user', 'preference', 'auth-token']
        lastname:
            groups: ['user', 'preference', 'auth-token']
        email:
            groups: ['user', 'preference', 'auth-token']
        preferences:
            groups: ['user']

Le cour a été écrit pour être suivi de manière linéaire. Il faut commencer par le début si tu veux en tirer un maximum de profit.

Normalement la sérialisation avec les groupes est abordée dans les chapitres précédents. Mais si elle est bien faite, la réponse ne devrait pas contenir le mot de passe.

Voir le chapitre : Relations entre ressources - Les groupes avec le sérialiseur de Symfony et même plus loin dans le chapitre Sécurisation de l’API 1/2, il y a un exemple concret.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# src/AppBundle/Resources/config/serialization.yml
# ...

AppBundle\Entity\User:
    attributes:
        id:
            groups: ['user', 'preference', 'auth-token']
        firstname:
            groups: ['user', 'preference', 'auth-token']
        lastname:
            groups: ['user', 'preference', 'auth-token']
        email:
            groups: ['user', 'preference', 'auth-token']
        preferences:
            groups: ['user']

Le cour a été écrit pour être suivi de manière linéaire. Il faut commencer par le début si tu veux en tirer un maximum de profit.

BestCoder

Je le suis de manière linéaire mais j’avoue ne pas avoir suivi la partie sur les relations entre les ressources car j’en avais pas besoin sur le coup. En ce qui concerne l’exemple concret dans la Sécu 1/2, je m’était arrêté dès que j’ai eu le retour du POST après la mise en place de l’encodage du mot de passe donc je ne risquais pas de le trouver. En tout cas merci pour la réponse :)

+0 -0

Super Tuto! L’api fonctionne à merveille avec Postman ;) La question que je me pose maintenant, c’est la partie Front de l’application web.

Dois je stocké le token dans un cookie ? et en javascript/jquery le rajouter dans le header ? N’y a t’il pas une faille de securité style CSRF ?

Encore merci pour ce tuto, il est parfait :)

Bonjour,

Je reviens vers vous car j’aimerais que le token soit mis à jour après chaque vérification de sa validité pour qu’il soit considéré comme expiré seulement après 1h sans requête à l’API.

Comment faire sachant que je n’ai pas l’EntityManager dans AuthTokensAuthenticator ?

+0 -0

Bonjour,

Tout d’abord merci pour ce tuto, j’avais besoin d’une api pour la création d’une application dans le cadre de mes études et c’est vraiment tres bien expliqué. Il y a une seule chose avec laquelle j’ai du mal bien que ce soit facultatif, serait il possible d’expliquer la démarche à suivre pour configurer le virtual host ? Je ne comprends pas bien ou doit on executer la commande : composer require symfony/apache-pack, ni la marche à suivre apres ??

Cordialement,

Salut, supper tuto, je l’ai adapter pour faire une API sous Sf4 juste un petit soucis avec l’erreur :

A circular reference has been detected when serializing the object of class "App\Entity\XXX" (configured limit: 1)

j’utilise bien les group mais il semble pas les prendre un compte, je précise que je n’utilise pas JSM mais le serializer de SF.

Je recherche donc des pistes .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
namespace App\Serializer;

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;


class Serialize
{

      private $serializer;

     public function __construct(){
        $encoders =  [ new JsonEncoder];
        $normalizers = [new ObjectNormalizer()];
        //$normalizers[0]->setCircularReferenceLimit(2);

        $this->serializer = new Serializer($normalizers, $encoders);
     }

     public function getSerialized($data, $type = 'json', $groups = []){
         return $this->serializer->serialize($data, $type, ['groups' => $groups] );
      }

}

ma class de service pourserializer ;)

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte