Introduction à la Living Documentation

Cet article fait suite au très intéressant lightning talk donné par Benoît Prioux (Lectra) à la conférence BDX I/O 2016 sur le sujet de la Living Documentation. Comme tout lightning talk, il ne fait que nous donner des pistes et des idées à creuser. C’est pourquoi, en plus de vous donner un aperçu de sa présentation, j’approfondirai le sujet en vous présentant la documentation d’API avec Swagger.

La documentation, cette tâche fastidieuse qui revient de plus en plus aux développeurs…

Nous devons écrire le code, les tests, les commentaires du code, la documentation technique, la documentation métier, la documentation des API, la documentation d’installation, etc. Beaucoup de temps passé au final. Mais pour quel résultat ? La documentation devient très vite obsolète, elle est fastidieuse à maintenir, le fait qu’elle soit dupliquée dans le code et les documents fait qu’elle peut finir par devenir erronée ou incomplète. Résultat ? On ne la lit plus, on va lire directement le code pour répondre à la question du Product Owner…

Pour résoudre ces problèmes, le concept de living documentation a été défini : on souhaite que la documentation se construise et se teste en même temps que le code. Elle est “vivante”, dans le sens où elle est toujours aussi à jour que le code. Elle vit et est modifiée au même rythme que le code.

Documentation technique

La documentation technique passe par exemple par des README, des tutoriels, de la documentation d’API.

Asciidoc et Asciidoctor

Asciidoc est un concurrent de Markdown. Il est utilisé pour écrire de la documentation dans des domaines variés. Pour citer un exemple du monde du logiciel, SpringFramework l’utilise pour sa documentation. Asciidoctor est un toolchain qui permet de convertir la documentation en HTML, PDF, etc.

La macro include permet d’inclure directement des fichiers du code source, pour illustrer la documentation : la documentation est toujours à jour avec le code source.

include::HelloWorld.js[lines=2..4]

Ainsi, la documentation se compile tout comme le code se compile ; intégrée à votre pipeline d’intégration continue, la documentation sera aussi à jour que le code.

Documentation métier

Avec le Behavior Driven Development (BDD), votre équipe écrit des spécifications exécutables, des tests automatisés qui s’écrivent dans un langage naturel. On n’est pas très loin donc d’avoir une living documentation du métier de votre application.

Cukedoctor

La plupart des outils de BDD génèrent seulement un rapport de test.

C’est là que Cukedoctor entre en scène. Basé sur Cucumber et Asciidoctor, cet outil permet de générer la documentation correspondant à vos scénarii de BDD, sans effort supplémentaire si vous utilisez déjà Cucumber pour écrire vos spécifications exécutables. Ainsi, vous obtenez une documentation lisible et toujours à jour des fonctionnalités de votre logiciel.

Autres outils cités par Benoît Prioux :

  • QDox : un extracteur de classes, interfaces et méthodes Java, pour générer de la documentation basée sur le code,
  • DOT : langage de description de graphes / arbres, permettant de compléter votre documentation par des informations plus visuelles,
  • dot-diagram : API Java permettant d’utiliser le langage DOT pour produire des graphes.

Approfondissement : documentation d’API

Les API sont des points critiques en terme de documentation : exposez une API sans la documenter et les consommateurs de votre service ne pourront pas/voudront pas l’utiliser. Si vous écrivez une documentation à côté de votre code, c’est déjà un bon point. Mais on en revient aux problèmes de maintenance, obsolescence et gestion des versions de la documentation par rapport aux versions de votre API. La solution est ici encore d’avoir de la documentation en tant que code.

Pour cela, vous pouvez utiliser Swagger. Swagger n’est pas un outil de documentation en premier lieu ; c’est un langage permettant de spécifier votre API, à partir duquel l’API peut être générée pour vous, et donc également la documentation interactive et toujours à jour.

Vous pouvez également intégrer les annotations Swagger à une API existante dans le but de la documenter. Dans le cadre de ma mission, je développe des micro-services avec Spring Boot, j’ai pu très facilement intégrer à ces micro-services une librairie basée sur Swagger : Springfox. Springfox simplifie l’intégration de Swagger au sein d’une application Spring Boot/Spring MVC : cela permet de générer automatiquement la documentation correspondant à vos contrôleurs Spring, sans autre ajout que l’annotation @EnableSwagger2 sur votre Application. Bien sûr, vous pouvez compléter/paramétrer votre documentation via les annotations Swagger et via l’ajout d’un Bean de configuration.

Pour illustrer cet article, j’ai créé une application Spring Boot ultra minimale basée sur l’exemple de la documentation Spring.

À travers 3 étapes très simples, je vais vous montrer ce qu’il suffit de faire pour générer une documentation vivante et interactive avec Springfox. Sur ce dépôt GitHub, vous trouverez une branche par étape.

Branche master : application Spring Boot minimaliste

Code source : https://github.com/Nephtys/springfoxexample/tree/master/src/main/java/greetings.

Sur la branche master vous trouverez l’application Spring Boot de la documentation Getting Started.

Vous pouvez la lancer via la commande :

gradle bootRun

et voir alors le résultat sur http://localhost:8080/greeting.

Branche springfox-base : auto-génération de documentation

Code source : https://github.com/Nephtys/springfoxexample/pull/3/files.

Pour demander à Springfox de générer automatiquement la documentation de votre API, il vous suffit d’ajouter les dépendances suivantes :

compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.6.0'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.6.0'

ainsi que l’annotation @EnableSwagger2 sur votre Application.

La dépendance Swagger-UI sert à générer une page HTML permettant de naviguer dans la documentation.

Vous pouvez voir la documentation Swagger sur l’URL http://localhost:8080/v2/api-docs (il s’agit de JSON) et la documentation Swagger-UI sur l’URL http://localhost:8080/swagger-ui.html.

La documentation est interactive. On peut tester l’appel à notre service directement depuis sa documentation :

On constate également que la documentation des URLs générées automatiquement par Spring Boot est présente (/errors) et que des informations non pertinentes sur des codes d’erreurs sont données.

Branche springfox-configured : configuration du Docket

Code source : https://github.com/Nephtys/springfoxexample/pull/2/files.

Pour corriger ces deux points, on peut ajouter un bean pour configurer le Docket de Springfox (un builder de configuration).

@Bean
public Docket api() {
 	return new Docket(DocumentationType.SWAGGER_2)
		.select()
		.apis(RequestHandlerSelectors.any())
		.paths(PathSelectors.regex("/greeting.*"))
		.build()
		.useDefaultResponseMessages(false);
}

Résultat :

C’est pas mal, mais ce n’est pas très détaillé : on pourrait décrire les paramètres, le bean de retour, etc., pour donner plus d’informations à l’utilisateur de notre API.

Branche springfox-configured-annotated : annotations pour décrire l’API

Code source : https://github.com/Nephtys/springfoxexample/pull/1/files.

Springfox nous met à disposition les annotations de swagger-api:swagger-core, dont la documentation se trouve ici.

Ainsi, à l’aide de quelques annotations, j’ai amélioré la description de l’API : on peut renseigner une description détaillée, des valeurs par défaut, l’ordre des champs dans un modèle de réponse, etc. J’ai également ajouté une description générale via la méthode apiInfo du Docket.

Le résultat est maintenant satisfaisant :

Avec cet outil, si j’ajoute un paramètre à la requête, un contrôleur à mon API, si je modifie l’objet retourné, etc., ma documentation sera mise à jour automatiquement au prochain build.

Conclusion

Mieux vaut prendre le temps d’automatiser sa documentation, ainsi on s’évite le temps perdu :

  • à mettre à jour la documentation à de multiples endroits,
  • à être induit en erreur par une documentation obsolète,
  • à aller directement lire le code car la confiance dans la documentation est perdue.

De cette façon, la documentation est écrite à un seul endroit. De plus, comme elle est liée au code, la gestion des documentations des différentes versions d’un code est simple à gérer. La confiance est retrouvée puisque, la documentation s’écrivant sous forme de code, la tâche devient moins fastidieuse !

Liens

Si le sujet vous intéresse, je vous recommande le livre de Cyrille Martraire : Living documentation, qui est très complet.