Le problème : un contrat qui dérive en silence
Chez DJUST, on pratique le design-first pour nos APIs. Concrètement : notre Product Manager écrit les contrats OpenAPI (en YAML, dans un repo Git dédié) avant que les développeurs commencent à coder. L'idée est noble — le contrat est la loi, le code s'y conforme.
Le problème ? On n'avait aucun moyen de vérifier que le code respectait effectivement le contrat.
Le développeur implémentait sa feature. Il générait son OpenAPI automatiquement via Spring Boot. Et le contrat de référence et le contrat généré divergeaient — parfois sur des détails (une description manquante, un champ renommé), parfois sur des choses plus sérieuses (un type de retour différent, un paramètre optionnel devenu obligatoire). Et personne ne s'en rendait compte immédiatement.
Ce n'est pas théorique. Un breaking change est passé en production fin 2024, touchant les pages de devis du BO et du FOC, parce que personne n'avait fait le diff entre l'ancienne et la nouvelle version du contrat. Notre PM l'a signalé dans #dev-teamleads : "Je ne peux plus faire les diffs à chaque version". Et il avait raison — ce n'est pas viable à la main.
Les tentatives précédentes
Ma première approche : un jar CLI. On compile, on lance, on passe les deux fichiers en arguments, on obtient un rapport. Fonctionnel mais pas pratique du tout — il fallait que chaque développeur installe Java, compile le projet, connaisse les arguments.
Notre QA senior n'allait pas se battre avec un jar à compiler à chaque fois. Et surtout, le vrai use case c'est de comparer rapidement un contrat écrit par le PM avec ce que génère le code — idéalement depuis un navigateur, sans friction.
Il fallait quelque chose d'accessible.
La construction : un jour, Vaadin, et beaucoup de plaisir
Fin janvier 2026, entre deux réunions et le lendemain matin, j'ai construit l'outil. Pas en React. Pas en Vue. En Vaadin.
Oui, Vaadin. Le framework Java que j'utilisais en banque. L'ancien truc "application logiciel à l'ancienne". J'avais le choix — React, Vue, Nuxt — et j'ai quand même pris Vaadin. Pourquoi ?
Parce que l'outil est destiné à des développeurs Java. Parce que je voulais un repo simple à déployer sur Google Cloud Run sans pipeline frontend complexe. Et parce que pour un outil interne avec cette ergonomie-là — deux zones de texte, un bouton, un rapport — Vaadin fait exactement le job.
Le code source est sur GitHub : [github.com/chetana/openapi-contract-diff](https://github.com/chetana/openapi-contract-diff)
Ce que fait l'outil
L'interface est volontairement simple :
- À gauche : collez le YAML de votre contrat Design-First (le contrat de référence écrit par le PM)
- À droite : collez soit le JSON/YAML généré par votre code, soit directement l'URL de votre endpoint api-docs (ex:
https://localhost:8080/v3/api-docs) - Comparez : l'outil isole les breaking changes techniques et les écarts de documentation
Ce que ça apporte concrètement :
- Les diffs de texte sont visibles — on voit exactement quelle description a changé ou est manquante
- Le tracking des descriptions dans les schémas imbriqués — souvent oubliés, mais essentiels pour nos partenaires intégrateurs
- L'identification par
operationId— l'outil n'est pas perturbé par un changement d'URL, il compare les opérations sémantiquement
Ce dernier point est important. Si on renomme une route (/v1/orders → /v2/orders), l'outil comprend quand même que c'est la même opération et compare les contrats correctement — à condition que l'operationId soit stable.
La réception dans l'équipe
L'annonce dans #oms-team a eu un écho immédiat. Un collègue back a voulu tester avec les events dès le lendemain. Notre PM a exprimé son impatience de l'essayer. Notre QA senior a été touchée que j'aie pensé à elle en faisant l'interface web plutôt que le jar CLI ("merci de penser à moi ^^").
C'est ça qui était satisfaisant — pas l'outil en lui-même, mais le fait qu'il répondait à un vrai besoin ressenti par plusieurs personnes.
Depuis, l'outil tourne sur Google Cloud Run. L'URL est partagée en interne. L'idée est de le migrer sur GitLab si son usage se confirme sur toute l'entreprise.
Les leçons
1. Le problème de dérive silencieuse est structurel dans le design-first
Si vous faites du design-first sans outil de vérification, votre contrat et votre code vont diverger. C'est inévitable. Les développeurs ne vont pas manuellement comparer les YAMLs à chaque PR — c'est trop fastidieux. Il faut automatiser cette vérification, idéalement dans la CI/CD.
L'outil web est une première étape. L'étape suivante, c'est de l'intégrer dans notre pipeline GitLab pour qu'il bloque automatiquement une merge request dont le code ne respecte pas le contrat.
2. L'outil simple > la solution parfaite
Vaadin n'est pas le choix le plus sexy. Mais l'outil était prêt en un jour et il fonctionne. Si j'avais attendu de construire une belle interface React avec tests E2E et pipeline CI/CD complet, j'aurais probablement mis deux semaines et l'équipe aurait continué à comparer les YAMLs à la main.
Done is better than perfect — surtout pour un outil interne.
3. Le operationId est sous-estimé
On ne met pas assez de soin dans les operationId de nos contrats OpenAPI. Mais pour qu'un diff soit pertinent — que ce soit avec cet outil ou avec n'importe quel autre — il faut que les opérations soient identifiables de manière stable. Un operationId bien nommé est un contrat en soi.
Et maintenant ?
L'outil est là, il tourne, il est utilisé. La prochaine évolution naturelle est l'intégration dans la CI/CD : à chaque PR qui touche un module exposant une API, une vérification automatique contre le contrat de référence.
Ce sera le vrai moment où le design-first devient vérifiable — pas juste une intention, mais une contrainte technique.
Chetana YIN — Février 2026
Engineering Manager chez DJUST. Code source : [github.com/chetana/openapi-contract-diff](https://github.com/chetana/openapi-contract-diff)
Commentaires
Aucun commentaire pour le moment.