Maintenir à jour sa documentation d'API avec Dredd !

2019-05-06 | Louis DUTEL

image article

Dredd dans les grandes lignes

Garder la documentation d'une API à jour est une chose difficile. Il est toujours possible que quelqu'un, un jour, oubli de la mettre à jour, et à partir de là, les erreurs/oublis peuvent s'enchaîner. Pour éviter ça il existe peu de solutions simples et efficaces. C'est là où Dredd intervient. Pour lier fortement la documentation à l'API, Dredd va générer une série de tests d'API par rapport à la documentation. Grâce à cela, dès que l'API va voir son fonctionnement modifié, les tests de Dredd vont échouer car la documentation ne sera pas à jour. L'idée est simple mais diablement efficace.
Dans un premier temps nous verrons l'écriture d'une documentation OpenAPI, car vous vous doutez bien qu'il nous faille respecter une certaine norme. Ensuite nous parlerons rapidement du fonctionnement de Dredd avant de voir son implémentation dans un second article.

Notre première implémentation de Dredd

Nous avions entendu parler de Dredd depuis un petit moment mais nous ne pouvions pas nous permettre de tester son implémentation sur nos projets actuels car ils étaient trop volumineux pour une implémentation facile et rapide. Mais suite à un problème interne par rapport au suivi des temps de travail sur un projet (aucun outil ne nous correspondait ou alors son coût était beaucoup trop élevé), nous avons décidé de développer notre propre outil de gestion de temps.
Pour faire simple, il a été développé avec un back office en Symfony accessible via API, et un front office en ReactJS. Pour s'intégrer parfaitement dans notre stack de gestion de projets, nous récupérons nos différentes tâches sur nos tableaux Trello pour ensuite noter un temps dessus et l'enregistrer dans notre application. Donc avec le développement de l'API de cet outil, nous avons décidé de tester Dredd.

L'écriture de la documentation

OpenAPI, qu'est ce que c'est ?

Anciennement nommé Swagger Spécification, OpenAPI est une spécification pour définir un standard à respecter pour désigner et documenter son API. Lancé par une Startup en 2010 (avec en parallèle le framework Swagger), le projet a attiré l’attention de nombreux développeurs (dont des géants de l'IT tel que Google, IBM, Microsoft ...), et est devenu la technologie la plus populaire pour désigner et décrire les API RESTful.

En janvier 2016 le projet Swagger Specification a été renommé OpenAPI Specification (OAS) et est passé sous la gouvernance de la fondation Linux. Selon le repository GitHub du projet, l'OAS définie un standard, une interface de description de langage de programmation agnostique pour les API REST, qui permet à la fois aux humains et aux machines de découvrir et comprendre les capacités offertes par un service sans avoir besoin d’accéder à son code, consulter une documentation supplémentaire, ou analyser le trafic réseau.

L'avantage d'utiliser la spécification OpenAPI pour décrire votre API, c'est que vous pouvez utiliser de nombreux projets open source pour générer une documentation interactive et dans notre cas, utiliser Dredd !

La structure d'un document YAML OpenAPI

Voici la structure de base d'une documentation YAML utilisant la spécification OpenAPI :

swagger: '2.0' #Version de la spécification OpenAPI
info: 
  version: Version de votre API 
  title: Nom 
  description: Description de l'API 
  termsOfService: Termes d'utilisation 
  contact: 
    name: Nom de la personne à contacter 
    url: Site Web  
    email: Adresse mail 
  license: 
    name: Nom de la licence 
    url: Site Web où obtenir les informations sur la licence  
host: hostname.de.l'api
basePath: "/chemin/de/base/de/l/API" 
consumes:
  - application/json #Ce que votre api consomme
paths: 
  "une/route/de/l/API": 
    get:
      summary: Resumé de la méthode
      description: Description de la méthode 
      parameters:
        - in: query
          name: parametre1
          type: string
          required: true
          description: Description du paramètre
        - in: body
          name: body
          schema:
            $ref: "#/definitions/ExempleDefinition"
          required: false
          description: Le body en JSON          
      produces: 
      - application/json 
      responses: 
        '200': 
          description: Description de la réponse 
          schema: 
            "$ref": "#/definitions/ExempleDefinition" 
definitions: 
  ExempleDefinition: 
    description: Description de l'object
    properties:
      propertie1:
        type: number
      propertie2:
        type: string
    required:
      - propertie1

Dans cette documentation il y a 3 grandes parties :

  • info : Dans laquelle il y a toutes les infos générales de l'API (version / licence / description / ...)
  • paths : Contenant toutes les endpoints de l'API avec les méthodes, ce qu'elles consomment, ce qu'elles produisent, les différents types de réponses avec leur schéma, ...
  • definitions : Où il y a la définition des différents objets que l'API produit/consomme avec les propriétés, leurs types et les propriétés requises.

L'écriture du YAML pouvant vite devenir problématique avec les indentations, vous pouvez utiliser l'outil en ligne Swagger pour rédiger la première version de la documentation. Pour la suite, quand il s'agira de petites retouches, votre IDE devrait suffire.

Pour connaître les entrailles de la spécification OpenAPI, n'hésitez pas à consulter la documentation sur le repo GitHub Vous noterez qu'actuellement il existe l'OpenAPI 3.0 mais Dredd ne la supporte pas entièrement, c'est pour cela que nous restons en OpenAPI 2.0.

Comme nous l'avons dit dans le paragraphe précédent, utiliser la spécification OpenAPI permet d'avoir accès à différents projets open source pour générer une documentation plus agréable à lire qu'un simple fichier YAML.
Dans notre cas, nous utilisons spectacle-docs qui permet de générer notre documentation en HTML.

Leur démo :

demo spectacle

Le fonctionnement de Dredd

Une fois notre documentation correctement rédigée nous pouvons enfin passer à l'utilisation de Dredd. Pour faire simple, l'idée principale de Dredd est de consommer votre documentation, créer toutes les requêtes correspondant à vos routes et comparer le résultat de chacune des requêtes avec ce qui est attendu.

Lors du lancement de la commande, Dredd va dans un premier temps valider votre description d'API et vous indiquer les erreurs et warning présents dans votre fichier. Ensuite il va vérifier la description, regarder les oublis de valeur pour les templates des URI, rapporter tous les body JSON imparsables, les paramètres d'URI invalides et les templates d'URI invalides. Enfin, si tout est valide, il va créer toutes les requêtes HTTP.

Il y a cependant certains types de route plus compliqués à tester via dredd, tel que des routes nécessitant le résultat de l'appel d'une autre route dans le corps de la requête. Il y aussi le cas où vous avez une authentification requise, Dredd ne va pas pouvoir générer seul le token nécessaire.
Pour palier à ça, il y a les hooks. Ils permettent de piloter Dredd en indiquant des actions à faire avant ou après certains événements. Notamment : "N'exécute pas ce test, il n'y aucun moyen qu'il puisse réussir" ou "Avant chaque test, je veux que tu me génères un token valide et que tu l'ajoutes aux headers dans la requête".
Nous pouvons faire beaucoup d'autres actions avec les hooks, tel que charger des fixtures dans la BDD, nettoyer après les étapes de tests, modifier la requête générée par la description d'API et bien sûr un peu de débuggage en logant ce qu'il se passe ;)

Conclusion

Vous l'aurez compris, le gros avantage de dredd c'est qu'avec une simple documentation nous pouvons avoir rapidement une série de tests automatisés pour chacun de nos endpoints d'API. Certes tous les tests ne fonctionneront pas directement avec la génération automatique, mais cela reste une bonne base avec un gain de temps considérable à la clé. Et en bonus, vous avez une documentation constamment à jour !
J'espère que cette introduction à Dredd (et par extension à OpenAPI) vous aura plu, on se retrouve bientôt pour voir comment l'implémenter.

Dredd OpenAPI Tests ReactJS