Blog
Développement d'un SaaS en tant que stagiaire informatique : partie 3
Présentation
Pravatar grandit jour après jour.
De nos jours, mon travail porte davantage sur les détails et la refonte que sur de nouvelles fonctionnalités, mais c'est peut-être la partie la plus importante d'un bon projet SaaS.
Backend
JSON : API
Afin de construire Pravatar sur des bases solides et maintenables pour les Belighters qui poursuivront le projet à la fin de mon stage, Philippe m'a demandé de modifier mon API pour la rendre conforme à la spécification JSON:API.
Cette spécification est assez simple et claire, elle décrit ce que votre API doit, peut ou doit demander et répondre.
Cependant, ces modifications m'ont fait reconsidérer cette API et m'ont aidé à augmentation le code qualité, mais m'a aussi fait apprendre beaucoup de nouvelles choses utiles.
Sérialiseur ActiveModel
Comme vous le savez peut-être, l'une des premières caractéristiques de JSON:API est que votre API doit répondre ou être demandée avec un seul objet de ressource contenant au moins ses identifiant et type.
Bien que cela me semble logique maintenant, étant donné que je veux suivre une architecture RESTful, je faisais quelques erreurs :
- Mes réponses et demandes d'API n'étaient pas correctement composées d'un seul objet de ressource (ou d'un tableau d'objets de ressources).
- J'étais en train de créer les réponses JSON dans le contrôleur d'API.
Comme les réponses doivent représenter un objet de ressource unique, le moyen le plus simple de transférer la responsabilité de représentation hors du contrôleur et de se conformer à la spécification est d'utiliser ActiveModel Serializer.
Cette gemme vous permet de définir des sérialiseurs définissant essentiellement la « représentation JSON » d'une ressource. Ces sérialiseurs seront utilisés lors de l'appel :
render json : your_resource
Ceci étant fait, j'ai réussi à supprimer des morceaux de code qui n'étaient pas censés être sous la responsabilité du contrôleur et à suivre correctement la spécification JSON:API.
De plus, lorsque mon API appelle désormais render json : profile, elle fait vraiment ce qu'elle signifie.
Il ne s'agit plus de rendre un JSON que j'ai créé précédemment, mais de rendre le ressource demandé par le client.
L'intention est clair et précis.
Jetons Web JSON
Pravatar était assez simple à l'époque, mais une question s'est rapidement posée après avoir implémenté le téléchargement : Comment s'assurer qu'un téléchargement est légitime ?
Lorsque j'ai examiné le problème pour la première fois, j'ai trouvé une solution maison.
Cette solution fonctionnait assez bien, mais j'ai découvert plus tard que JSON Web Tokens était le bon choix pour résoudre le problème, pour les raisons suivantes :
- C'est un moyen efficace de communiquer une petite charge d'informations entre deux sources via un transport non sécurisé
- Il peut être envoyé dans un en-tête HTTP
- Il est signé avec un code secret (nos clés API dans ce cas)
Cela m'a permis de suivre la JSON:API et d'envoyer des méta-informations liées à la demande et non directement à la ressource dans le JWT.
Placer ces champs (comme la date et l'heure du téléchargement) dans la charge utile du JWT et les signer avec la clé API était le moyen le plus simple de garantir la validité du téléchargement.
JWT fournit également une solution d'authentification via des API.
Frontend
Browserify
À un moment donné du projet, une chose terrible s'est produite : mon javascript a tout fonctionné spaghetti; l'extrait était un fichier de code unique composé de plusieurs fonctions s'appelant les unes les autres.
J'exagère un peu, mais je peux être sûr que cela aurait été un véritable gâchis avec la croissance du code.
C'était le moment de passer à l'action.
Ce qui est amusant, c'est que j'ai déjà inclus le bon outil pour y parvenir dès le début : le génial Browserify.
J'ai divisé le code en modules, chacun étant une classe et ayant ses propres responsabilités.
Alors, comme je l'exige jquery dans le module principal pour le regroupement, je peux avoir besoin de mes autres modules, en me fournissant une instance de la classe avec ses fonctions publiques.
Organiser votre code avec Browserify vous oblige à répartir correctement les responsabilités entre vos modules.
En effet, si votre module A nécessite le fonctionnement du module B mais que B nécessite également A, vous créez un dépendance circulaire cela empêchera l'exécution de votre script.
Moteur
Tant qu'il n'y avait aucune fonctionnalité de sécurité dans Pravatar, le client pouvait simplement utiliser l'extrait javascript et écrire des balises HTML pour récupérer et télécharger les avatars.
La mise en œuvre du système de sécurité impliquait de trouver un moyen de faire en sorte que le client génère le JWT avec son Clé API.
J'y suis parvenu en créant un joyau pour une application cliente Rails. Cette gemme est un moteur qui fournit au client :
- Méthode Helpers pour créer des balises de récupération et de téléchargement
- Un générateur pour copier les modèles HTML des générateurs et permettre aux clients de les modifier à leur guise.
Le client n'a qu'à installer la gemme et à définir sa clé d'API dans secret.yml, puis il est prêt à utiliser Pravatar.
Conclusion
Je me rappelle avoir pensé à quel point j'étais loin de terminer ce projet au cours de mes premières semaines chez Belighted.
En fait, je suis très impressionné de voir ce que j'ai appris au cours de ces sept semaines et ce que je suis capable de réaliser aujourd'hui.
Je suis très reconnaissante à Belighted de m'avoir prise comme stagiaire et de m'avoir fait progresser à ce point.
Il reste encore six semaines de stage à savourer !