Rails API
Une formation interne @Capsens
6. Tests
7. Ressources complexes
8. Déploiements
9. Versionning
10. Mobile
1. Présentation d'une API simple
2. Authentification
3. Rôles & permissions
4. Documentation
5. Process de communication Back/Front
Programme
Présentation d'une API simple
- render au format json
- pagination
Controler
- hérite de ActionController::API
- gestion d'erreur "standard"
Application Controler
- Possibilité d'avoir plusieurs serializer par ressource
- attention aux "has_many" qui font des n+1 et ignorent la pagination
Serializer
4. Creer la base de donnees : rails db:create db:migrate db:seed
5. Lancer le serveur : rails s
6. Verifier que l'API repond : GET http://localhost:3000/api/v1/products
Setup d'un environnement local de test
1. Telecharger et installer Postman (https://postman.com/downloads)
2. Télécharger l'API démo https://github.com/petrachi/ecommerce_api
3. Installer les dependances : bundle install
Exercice
Authentification
JWT vérifié par un tiers
- Délégation des contraintes de sécurité au tiers
- Facilement scalable et partageable entre plusieurs services
Access Manager
JSON Web Token
- Simple à implémenter
- Mécanique d'expiration
- Le contenu du token est variable (on peut y mettre un user, des permissions, etc)
JWT
Token dans le header
- Très simple à implémenter
- La clé doit rester secrète
- Peut convenir pour des communication entre deux services interne
Header
Header
JWT
Access Manager
4. Automatiser le processus avec les variables postman
1. Se connecter via postman http://localhost:3000/api/v1/login
2. Récupérer le token de connexion
3. Récupérer la liste des produits en s'authentifiant http://localhost:3000/api/v1/products
Exercice
Rôles & permissions
- Le token de connection inclut les permissions de l'utilisateur, le back ne fait que le lire
- Permet de partager la ségregation des permissions à travers plusieurs services
Permissions dans le JWT
- Le token de connexion inclut le rôle de l'utilisateur connecté
- Le front peut utiliser le rôle pour obtenir différentes informations à différents endroits de l'application
- Le back peut customizer les réponses en fonction du rôle souhaité
Rôles dans le JWT
- Toutes les permissions sont gérés au regard de l'utilisateur connecté
- Les permissions peuvent être ultra-précises
Interne à l'application
Interne à l'application
Roles dans le JWT
Permissions dans le JWT
Documentation
- On écrit la doc à priori ou à posteriori ?
- On concentre les efforts sur la précision du typage du schema de donnée ?
- Ou sur des exemples d'usages ?
- On écrit la doc via des outils automatiques, ou à la main ?
Quelle doc
Mes collégues dev back ?
Mes collégues dev front ?
Des devs front externes ?
Quelle cible ?
Outil semi-automatique
S'intégre aux scénarios de tests
Gem rswag-specs

Permet d'exposer une UI interactive à partir des swagger générés
Gem rswag-ui
4. Copier le token via le boutton "Authorize"
5. Récupérer la liste des produits qui coûtent moins que 500
1. Aller sur http://localhost:3000/api-docs/index.html
2. Essayer de récupérer la liste des produits qui coûtent moins que 500
3. Se connecter via l'action "login"
Exercice
Process de communication Back/Front
Contexte :
Une équipe Front et une équipe Back
Problématique :
Comment on fait pour travailler en même temps sur le même feature ?
Partage d'expérience
Solution en 3 étape :
- Les deux équipe font une conception technique commune de la feature
- Il faut surtout réfléchir à la structure de donné
- De quoi a besoin le front comme information ?
- Comment le Back va organiser ça dans son schéma de DB ?
- Tous les endpoints nécessaires sont écrits dans le ticket
- Le schéma de donnée est écrit
- Les noms sont définitifs
- Ce qui est écrit dans le ticket fait loi
- Le front et le back peuvent travailler en même temps
- Le front utilise des mocks le temps que le back ait fini
- Le back écrit la documentation définitive à posteriori grâce à des outils automatiques
1. Réflexion sur l'intégration de ces contraintes chez Capsens
2. Écriture des guidelines de workflow de développement d'API
Exercice
Tests
Avec une API, les tests d'intégration sont des tests end-to-end
Je vous renvoie à cet article pour plus d'informations
https://www.rubybiscuit.fr/p/ecrire-des-tests-qui-evitent-les
Quels tests écrire ?
Postman permet également de créer des scénarios de tests
Peu d'avantages comparé à des tests intégrés à Rails
Alternative Postman
4. PATCH /products/:id -> modifier le titre
5. GET /products/:id -> verifier la modification
6. DELETE /products/:id -> supprimer le produit
7. GET /products/:id -> verifier la supression
Écrire dans postman un scénario de test CRUD classique
1. POST /auth/login -> sauvegarder le token de connexion
2. POST /products -> creee un produit et sauvegarder l'id
3. GET /products/:id -> verifier la creation et un champ du produit
Exercice
Ressources complexes
L'application propose un endpoint différent pour chaque besoin, même sur la même ressource
- Le code de chaque endpoint est indépendant du reste du code de l'API
- Le code des endpoints qui utilisent la même ressource risque d'être dupliqué, et de se désynchroniser avec le temps
- Le front est totalement dépendant du back pour personaliser ses appels
Endpoint dédié
L'application propose des endpoints "tous les mêmes", mais qui possédent de grandes capacités de personalisation
- Le code de chaque endpoint est simple
- Le code "coeur" de l'API est complexe et risque d'être difficile à maintenir
- Le front est autonome pour personaliser ses appels
Endpoint générique
Exemple où les associations sont gérées de façon génériques.
Endpoint générique

Exemple de deux serializers differents où les associations sont incluses ou non en fonction des besoins de la feature
Endpoint dédié

Déploiements
1. Toujours déployer le Back avant le Front
2. Toujours tester la rétro-compatibilité avant de déployer
Points d'atttention
QCM #1
Je valide cette PR ?
Je demande des changements ?
QCM #1
Je valide cette PR ?
Je demande des changements !
Il faut mettre une valeur par défaut sinon tu casse la rétro-compatibilité.
QCM #2
Je valide cette PR ?
Je demande des changements ?
QCM #2
Je valide cette PR ?
Je demande des changements !
Il faut supprimer cette colonne en deux deploy, sinon tu casse la retro compatibilité.
Met ta migration dans un autre deploy.
QCM #3
Je valide cette PR ?
Je demande des changements ?

QCM #3
Je valide cette PR ?
Je demande des changements !

Tu ne peux pas renommer de colonne c'est interdit. Tu dois créer la nouvelle colonne et dupliquer les données existantes. Et supprimer l'ancienne dans un second deploy
rename_product_stock.rb
rename_product_stock.rb
QCM #4
Je valide cette PR ?
Je demande des changements ?

QCM #4
Je valide cette PR ?
Je demande des changements !

Tu ne peux pas renommer la colonne dans le serializer non plus, c'est la même logique que pour la migration
QCM #5
Je valide cette PR ?
Je demande des changements ?

QCM #5
Je valide cette PR ?
Je demande des changements !

Tu ne peux pas modifier le format d'un champs dans le serializer sans casser la rétrocompatibilité
QCM #6
Je valide cette PR ?
Je demande des changements ?

QCM #6
Je valide cette PR !
Je demande des changements ?

Je suppose que tu sais que tu casse la rétro-compatibilité ici, mais vu que c'est pour corriger une faille de sécurité c'est OK
QCM #7
Je valide cette PR ?
Je demande des changements ?

QCM #7
Je valide cette PR ?
Je demande des changements ?

Ça dépends !
On a bien la confirmation que le front a modifié ses requêtes pour explicitement passer le param de sorting sur le nom là où ils en avaient besoin ?
QCM #8
Je valide cette PR ?
Je demande des changements ?

QCM #8
Je valide cette PR ?
Je demande des changements ?

Ça dépends !
On a bien la confirmation que le front interceptent aussi bien les erreurs 422 que les 400 ?
Versionning
Vous mettez votre code d'API dans un dossier "v1", "v2", etc
Vous utilisez le code pertinent en fonction de l'url, ou d'un header, ou d'un param
La pratique
Vous devez faire évoluer votre API par gros changements
Un petit changement ne suffit pas à justifier la duplication de toute la base de code liée à l'API
Dans un contexte d'amélioration continue, il est probable que vous ayez une v1 pour toujours
Intégrer une mécanique de feature flag / déprecation warnings est peut-être plus approprié
Inconvénients
Vous pouvez avoir plusieurs versions de l'API qui fonctionnent en même temps
C'est bien plus pratique pour permettre aux clients de l'API pour se mettre à jour
Ce qui est probablement nécessaire si vous faites une API qui est consommée par des clients externes, avec qui vous avez peu de communication
Avantages
Sur chaque réponse de l'API Back, vous ajoutez un champ "deprecation", qui est habituellement vide
Si une feature évolue, vous activez ce flag "deprecated" sur l'ancien comportement
Le front met en place un mécanisme, dans ses tests automatiques qui renvoie une alerte si le flag "deprecated" est rempli
Deprecation Warning
1. Le front envoi sur chaque requête son "numéro de version front"
2. En fonction, le back va répondre avec le nouveau comportement ou l'ancien comportement
Feature Flag
Mobile
3. Coupures réseau
Il faut anticiper et mettre en place des mécanismes de récupération en cas de coupure réseau
Il faut aussi prévoir que les requêtes n'arriveron pas nécessairement dans le bon ordre
2. Les appstores doivent valider les nouvelles version des applications
Vous n'avez pas entièrement le contrôle sur le moment de déploiement de la nouvelle version
Difficile aussi de faire un hotfix sur le front en cas de bug
1. Les utilisateurs contrôlent la mise à jour de leur application (front).
Il faut donc assurer la rétro compatibilité sur de longues périodes
Partage d'expérience : environ 10% des utilisateurs avaient une version datant de +6mois
Quelques challenges spécifiques
5. Prévoir du stockage local côté front
Et donc, peut-être, considérer un envoi des données basé sur un diff (à la git)
4. Attention à la consomation de Data et de batterie
Il faut privilégier les approches qui demandent le moins de requêtes possibles
Ainsi que des requêtes les plus légéres possibles (dans les deux sens)
Quelques challenges spécifiques
Fin
API trainig at Capsens
By Thomas Petrachi
API trainig at Capsens
- 1