PHP     Symfony 2 et 3       AngularJS   Angular2       Cordova/Ionic 2
Daniel G.
Développeur d'applications Web et mobiles - Gironde

SAVOIR-FAIRE

La théorie :

REST (representational state transfer) est un style d'architecture qui repose sur le protocole HTTP. On accède à une ressource (par son URI unique) pour procéder à diverses opérations (GET lecture / POST écriture / PUT modification / DELETE suppression), opérations supportées nativement par HTTP.

API REST : wikipedia
La pratique :

Le Projet :
  • Un catalogue de Produit (nom, description, prix, prix d'achat, ID catégorie)
  • Une liste de catégorie (nom)

Prise en compte :
  • du versionning
  • utilisation de filtre et tri
  • affichage par lien Hateos de la catégorie d'un produit
  • gestion des groupes (Min, Full)
  • la documentation
  • Sécurisation par token

Exemples :
urldescriptiongroupe
GET /api/v1/produits?prix=600&sort=DESC Afficher tous les produits avec un filtre (prix inférieure à ...) et un tri ( ASC ou DESC) Min
GET /api/v1/produits/1 afficher un produit ayant ID=1 Full
POST (les données dans le corps) /api/v1/produits créer un produit Full
GET /api/v1/produits/1/categorie afficher la catégorie d'un produit Min / Full

Affichage des élements d'un produit en fonction du groupe :
[groupe]idnomdescriptionprixprix achatcatégorie
Min lien Hateos * * lien Hateos
Full * et lien Hateos * * * * lien Hateos


Présentation des bundles Symfony

FOSRestBundle :
Un de ses atouts majeurs est qu'il permet de générer des routes automatiquement (et les urls associées) à partir de noms d'actions dans les contrôleurs. diverses annotations dans le controller (view, filtre...)

JMSSerializerBundle :
- La sérialisation au format souhaité en sortie d'action de controleur
- Determiner quels sont attributs qui seront prises en compte(@expose) et la gestion des groupes dans les entités (@group diverses annotations dans les entités (expose, group...)

BazingaHateoasBundle :
Ajouter un lien de navigation (au lieu d'un ID) dans les ressources retournées via REST.

NelmioApiDocBundle :
Une Doc accèssible pour l'utiliseur qui présente votre API et sa façon de l'utiliser.

FOSUserBundle :
Gestion des utilisateurs connexion/inscription

FOSOauthServerBundle :
Délivre ou pas un ACCESS_TOKEN pour pouvoir accèder aux ressources REST.


Le vocabulaire :
Resource Owner :détenteur des données
Resource Server : le serveur de ressources avec les données protégés
Client Application : le client (appli mobile, site php...)
Authorization Server : délivre les tokens aux clients

Le Resource Server et Authorization Server sont applicativement et physiquement en général sur le même serveur.


+----------+              GRANT_TYPE=password
|.Resource.|
|..Owner...|
|..........|
+----------+
.....v
.....|....Resource Owner
.....|.Password Credentials
.....|
.....v
+---------+..................................+---------------+
|.........|>========= Resource Owner =======>|...............|
|.........|.........Password Credentials.....|.Authorization.|
|.........|..................................|.....Server....|
|.........|<========= Access Token =========<|...............|
|.........|....(w/ Optional Refresh Token)...|...............|
|.........|................................. +---------------+
|.........|
|..client.|..................................+---------------+
|..Appli..|..................................|...............|
|.........|> =====GET PRODUITS ============> |...............|
|.........|........ + ACCESS_TOKEN ..........|..Resource.....|
|.........|..................................|...Server......|
|.........|..................................|...............|
|.........|< =======PRODUITS============== < |...............|
|.........|........xml ou json...............|...............|
|.........|..................................|...............|
+---------+..................................+---------------+
        

CLIENT API REST

Le site de blog que vous consultez actuellement sera un client application de l'API REST. Celui ci pourra effectuer des demandes d'ACCESS_TOKEN et accèder avec celui çi aux données.
A faire qu'une seule fois : il faut inscrire le site de blog en tant que client application sur la base de l'Authorization Server ainsi ce dernier refusera toute requête ne provenant pas du site de blog.

Grant_type=password

J'ai choisi ce type d'autorisation car l'authorization server et le resource server se trouvent sur le meme serveur. Il y a donc peu de problème de sécurité à ce qu'un mot de passe circule entre les 2 applications.

La théorie :
1) Le Resource owner se connecte au site de blog.
2) le client application fait une demande d'ACCESS_TOKEN à l'Authorization server avec l'id et mot de passe du resource owner
3) l'Authorization server connait le client application et donc recherche dans la base client le Resource owner.
Si trouvé, envoit un ACCESS_TOKEN au client application
4) le client application envoit une requête d'accès aux données de l'API du Resource server avec l'ACCESS_TOKEN
5) le Resource server envoit les données.

La Pratique :
1) Pour simplifier le tutoriel ici même, je n'ai pas intégré de connexion. On simule une connexion utilisateur, celui ci a été enregistré en base de donnéee (identifiant: user password: user).

2) Le client application utilise guzzleHttp pour effectuer la requête de demande d'ACCESS_TOKEN et les requêtes API REST.

                POST http://apirest.eventoo.fr/oauth/v2/token

                BODY -> x.www.form.urlencoded
                grant_type:password -> le type authentification
                username:user -> identifiant du Resource owner : internaute qui se connecte
                password:user
                client_id:1_randomid -> 1_randomid <--> [ID client application]_[code texte]
                client_secret:secret
                scope:user  -> peut servir pour gèrer les rôles,
                            -> ainsi on peut faire correspondre le scope:user avec le rôle ROLE_USER de utilisateur connecté
        
3) Authorization server vérifie la validité du client application et de l'utilisateur qui demande la requête.
si ok : envoit de l'ACCESS_TOKEN ci dessous au client application:

            {
              "access_token": "OWQ4Njg0MTA3MWQ3MmUzNjA5OWY3NmMyZjVhYjQ2ZWE4OTU1YTc0ZDIxYWE3MzY2ZWE2OTBjNTc5NWE3M2RjMQ",
              "expires_in": 3600,
              "token_type": "bearer",
              "scope": "user",
              "refresh_token": "Y2YxZmFiNjMwNDczZmI2NmY1MzQ1NzRkYWI0OWJhNjU3ZTM2MjAzMTFjNGY4MzYwYjA3ZGJmM2IxN2JkNGZmOA"
            }
        
4)

           GET http://apirest.eventoo.fr/api/v1/produits/1.xml
                dans le corps de la requête :
           Authorization: Bearer OWQ4Njg0MTA3MWQ3MmUzNjA5OWY3NmMyZjVhYjQ2ZWE4OTU1YTc0ZDIxYWE3MzY2ZWE2OTBjNTc5NWE3M2RjMQ
        
5)
<link rel="_self" href="/api/v1/produits/1/categorie"/>
</categorie>
<prix>699</prix>
<prix_achat>610</prix_achat>
<link rel="_self" href="/api/v1/produits/1"/>