Une documentation vivante et utile

Nicolas Poste
Ceetiz
Published in
8 min readMar 5, 2021

--

Chez Ceetiz, nous sommes très attachés aux bonnes pratiques de développement, à l’efficacité, mais également au partage !

💭 C’est d’ailleurs pour ça que nous partageons cet article avec vous… 😊

(Annie Spratt, unsplashed)

La documentation est une source de partage d’information primordiale mais qui a bien trop souvent de nombreux défauts. Faite trop tard, non mise à jour et donc obsolète et j’en passe, une documentation se doit d’être utile mais aussi vivante ! On parle d’ailleurs en anglais de Living Documentation.

📚 Cyrille Martraire a écrit tout un livre sur la Living Documentation, très complet, une référence !

Un des problèmes de la documentation parmi tant d’autres, c’est que plus elle rentre dans les détails, plus elle sera rapidement obsolète.

Il ne faut pas oublier pas les valeurs de l’agile, mentionnée dans le Manifeste Agile :

Nous découvrons de meilleures approches du développement logiciel en le pratiquant et en aidant les autres à le pratiquer. Ce travail nous a amené à accorder de l’importance :

- aux individus et leurs interactions plutôt qu’aux processus et aux outils ;
- à un logiciel fonctionnel plutôt qu’à une documentation exhaustive ;
- à la collaboration avec les clients plutôt qu’à la négociation contractuelle ;
- à l’adaptation au changement plutôt qu’à l’exécution d’un plan.

Cela signifie que, bien qu’il y ait de la valeur dans les éléments situés à la fin, notre préférence se porte sur les éléments qui se trouvent en première partie de phrase.

Dans cet article, nous vous partageons nos différentes réflexions et approches sur la rédaction de la documentation qui répondent à nos besoins.

Une documentation efficace, qu’est-ce donc ?

Pour répondre à cette question, il faut en premier savoir ce qui doit être documenté !

Nous documentons le fonctionnel, et plus exactement le comportement.

Le code doit quant à lui être suffisamment clair. On parle de code auto-documenté. Il doit bien évidemment répondre au besoin fonctionnel. J’en parlais déjà il y a quelques années dans un autre article “La base de toute réussite : les bonnes pratiques”.

Il peut arriver qu’un détail technique ait besoin d’être documenté et nous faisons alors le choix de placer cette documentation la plus proche du code. Exit donc les solutions de wiki externe qui ne sont d’ailleurs quasiment jamais mis à jour en même temps que le code, ni même versionnés de la même façon.

Notre documentation trouve sa place à l’intérieur du repository Git, et si ce n’est dans le code, elle est à côté du code !

Les choix pris à Ceetiz

Un peu d’outillage a certes été mis en place, mais il reste simple et apporte de gros gains sur la mise à jour et l’utilisation des documentations.

Nous utilisons différents outils, qui combinés, nous offrent de belles fonctionnalités :

  • Material for MkDocs, ce qui implique que la documentation est rédigée en Markdown)
  • GitLab Pages, pour l’hébergement de la documentation
  • Swagger UI
  • Un peu de développement maison :)

Pourquoi du Markdown ?

Il est vrai que nous aurions pu utiliser le markup AsciiDoc, néanmoins la simplicité d’utilisation de Markdown, ses nombreux plugins qui viennent étendre son utilisation, en plus des nombreuses fonctionnalités offertes par Material for MkDocs, en font un choix tout à fait pertinent.

Pour nous, un des avantages du Markdown par rapport à AsciiDoc est qu’il est nativement géré par GitLab.

Les avantages d’un Markup tel que Markdown et AsciiDoc sont que :

  • la documentation est lisible même sans rendu
  • la syntaxe est simple et la mise en forme facile
  • le document est versionné
  • il est facile de générer de la documentation de façon automatique

💡 L’important, c’est d’utiliser un markup lisible sans interpréteur, versionable, facile à utiliser et à générer.

Que nous propose Material for MkDocs ?

Son UI est agréable, la navigation entre les pages est au top, les icônes de Font Awesome sont on ne peut plus faciles à incorporer.

Cet outil propose qui plus est nativement un système de recherche, une table des matières, des blocs de type “Admonitions” pliants ou non, ainsi que tout un tas de plugins (en provenance de mkdocs). Les modifications peuvent être réalisées à chaud et le rendu est immédiat sur un process qui tourne en local.

Et GitLab Pages alors ?!

Il est très facile de déployer des pages statiques sur GitLab Pages, accessibles en permanence sans surcoût et, en tant que grands utilisateurs de GitLab, les permissions sont gérées par un système d’autorisation très efficace : Seuls les membres, ou Tout le monde.

💡 D’ailleurs, le portail développeurs que nous exposons à nos partenaires est déployé sur GitLab Pages.

Nous utilisons Swagger UI

Cet outil nous permet d’exposer et d’exploiter la documentation OpenAPI 3.0, automatiquement générée lors du build de nos applications.

Cette documentation est ainsi à jour en permanence, puisqu’elle reflète à la perfection le code dans son état du moment. Si le code est modifié, la documentation est automatiquement mise à jour.

Nous recommandons d’opter pour une convention de commits

Les commits sont très souvent regardés par les développeurs pour comprendre le code, connaître son historique. Il est important d’attacher un soin particulier aux commits, et notamment aux messages.

Une convention répandue est à connaître, il s’agit de Conventional Commits. L’inspiration a été donnée par Angular, avec les mots clés build, ci, docs, feat, fix, perf, refactor, style, test, qui permettent de rapidement comprendre l’objectif du commit.

Cette convention de commits permet l’intégration de tâches d’automatisation autour de la construction du Changelog, tel que peut le faire cet outil, directement en Markdown !

💡 Sur GitLab, il existe des Push Rules qui permettent de bloquer tout push qui ne respecterait pas une certaine syntaxe.

Qui dit documentation, dit également rédaction des User Stories !

Les User Stories représentent une partie de la documentation, et à cet effet, leur rédaction est également très sensible : il est indispensable qu’elles restent le plus fonctionnel possible, qu’elles expriment le besoin et non la solution technique (qui est d’ailleurs trop souvent rédigée bien avant son développement).

Exit les termes techniques qui indiquent par exemple qu’il faut ajouter tel filtre à tel endpoint, on dira plutôt qu’il faut permettre de chercher des activités par destination par exemple.

Peut-être que la solution technique la plus appropriée ne serait pas celle décrite dans l’US ?! Cela signifie que qu’il faut mettre à jour l’US après le dev (dans un monde parfait, pourquoi pas, mais qui fait ça ?).

De plus, cet endpoint peut changer de nombreuses fois au cours de la vie du produit et l’US deviendrait donc caduque assez rapidement. Le besoin exprimé reste quant à lui a priori valable pour un bon moment !

Nos choix en ce qui concerne le découpage technique

Nous suivons les principes de conception décrite dans DDD (cf mon article “Optez pour une architecture pertinente et pérenne”), le découpage de nos applications est orienté fonctionnel, et il a été réalisé avec le métier.

Après nous être longuement interrogés et avoir lu de nombreux avis et articles, nous avons choisi d’utiliser un mono repo, ce qui nous apporte beaucoup plus de souplesse sans pour autant dégrader la qualité.
Dans ce mono repo, nous retrouvons un module Maven par application.

Nos implémentations suivent l’architecture hexagonale, avec un parti pris qui est de séparer clairement les couches de domaine, infrastructure et application, sous forme de sous-modules Maven :

  • la couche domaine est agnostique de tout framework et contient le modèle (non anémique !) ainsi que les uses cases
  • la couche infrastructure contient les adaptateurs de droite
  • la couche application contient les adaptateurs de gauche et la glue (IoC)

Chaque application est structurée de la même façon.

Nous documentons les Uses Cases

Comme dit précédemment dans cet article, nous documentons le comportement.

Nous avons à cet effet créé une annotation ‘@UseCase’ qui permet d’indiquer :

  • une description courte du use case, qui se veut fonctionnelle
  • une explication plus détaillée de ce qu’il fait
  • d’éventuelles classes liées

Ces annotations sont détectées automatiquement par un petit bout de code lancé lors du build (exec-maven-plugin). Ce code exploite la librairie classgraph et écrit de la documentation Markdown reprenant les informations déclarées dans les annotations et en plaçant différents liens. De l’introspection est utilisée afin de lister la ou les méthodes publiques de la classe.

Ainsi, nos uses cases sont listés sur une page et détaillées sur une autre, de façon unitaire.

Voici un exemple de documentation automatiquement créé à partir de l’annotation ‘@UseCase’, présente dans la classe ‘CreateUser’ :

@UseCase(
value = "Create a user from B2C context",
description = """
This use case creates a new customer (added to CUSTOMER group) and sends a welcome mail

Some of the errors include those reasons (represented by `CreateUserException.Reason`):

- USER_ALREADY_EXISTS
- EMAIL_IS_ALREADY_ASSOCIATED_TO_A_USER
""",
see = CreateUserException.class
)
Use Case ‘Create User’

Les liens présentés renvoient directement vers le code source, exposé sur GitLab.

Notre documentation d’à côté

Pour la documentation un peu plus complexe, nous avons choisi de placer des fichiers .md (Markdown) directement à côté de la classe du domaine liée, vraiment pas loin du coup ! Elle est versionnée avec le code.

Nous avons intégré l’extension plantuml_markdown, ce qui nous permet d’établir des diagrammes de séquence, également versionables, et lisibles même sans moteur de rendu.

Ces fichiers sont recopiés par le job “pages” de GitLab-CI et placés (sous forme de lien pour permettre la modification en live) dans le dossier de la documentation.

Afin de respecter l’arborescence et étant donné notre convention de package “com.ceetiz.-application-.-couche-.*” (ex: com.ceetiz.midas.domain), ainsi que l’utilisation des sous-modules Maven, nous déplaçons les fichiers ainsi (sûrement optimisable) :

# pour chaque fichier .md dans notre arborescence des micro-applications
for pathname in $( find . -name '*.md' -not -path "*/documentation/*" -not -path "./README.md"); do
dirs=$(echo $pathname | cut -d '/' -f 2-3)
lastDir=$(echo $pathname | rev | cut -d '/' -f 1 | rev)
if [[ "$dirs" == *"$lastDir" ]]; then
dirs=$(echo $pathname | cut -d '/' -f 2)
if [[ "$dirs" == *"$lastDir" ]]; then
dirs=""
fi;
fi;

mkdir -p documentation/docs/$dirs
ln -sf $(pwd)/$pathname documentation/docs/$dirs
done;
# recopie du fichier README en tant qu'index de la documentation
ln -sf $(pwd)/README.md documentation/docs/index.md

Le BDD en tant que documentation

Le Behavior Driven Development consiste à exprimer un use case de façon collective sous forme de scénario compréhensible par toutes les personnes du produit. Il est donc tout à fait adapté de les inclure dans la documentation produite car ces scénarios aident à comprendre le fonctionnel.

La construction de notre documentation dans son ensemble

Le job “pages” sur Gitlab-CI construit alors un site Material for MkDocs avec :

  • la documentation “statique” disséminée dans le mono repo
  • la documentation des uses cases générée lors du build
  • la documentation OpenAPI générée lors du build
  • le changelog généré par une ligne de commande dans le job pages

et ajoute les pages statiques Swagger UI (.html, .js, .png, …) à l’ensemble avant d’exposer la totalité sur GitLab Pages, rendant cette documentation à jour et utilisable à chaque push sur la branche master !

D’autres formes de documentation et de partage

La revue de code

La revue de code est un excellent moyen de partager des informations, échanger des points de vue, mais aussi d’homogénéiser le code. J’en parle plus longuement dans mon article “Travaillez efficacement en équipe avec la revue de code”.

En bonus, l’utilisation de Code Stream

Ce plugin, fort bien intégré à IntelliJ mais également à VS Code, permet de commenter, d’échanger, … autour de lignes de code, et donc directement au sein de votre IDE. La documentation la plus proche du code possible !

Et vous, quelles sont vos approches ?

Nous sommes en perpétuelle quête d’amélioration, adorons re-challenger nos décisions, et serions donc par conséquent curieux de connaître vos approches en ce qui concerne la rédaction d’une documentation efficace, et utile !

Nous partageons également sur d’autres articles !

Si la Clean Architecture vous intéresse, lisez sans plus attendre comment nous l’avons implémentée en mettant l’accent sur les Use Cases.

D’autres articles sont à venir, n’hésitez pas à nous suivre 😉

--

--

Nicolas Poste
Ceetiz
Editor for

CTO @ Ceetiz, passionné par le Software Craftsmanship, les aspects techniques, d'automatisation pour gagner en efficacité, Docker, ...