Code-first vs Design-first : une décision d'architecture souvent négligée

Quand une équipe commence à exposer des APIs, elle choisit rarement explicitement entre deux approches. Elle fait ce qui est naturel : les développeurs écrivent le code, Spring Boot (ou NestJS, ou FastAPI) génère automatiquement le Swagger, et voilà — l'API est "documentée".

C'est le code-first. Et c'est le choix par défaut de 90% des équipes.

Le problème, c'est que cette approche place la structure interne du code au centre. Les noms de classes Java deviennent des noms de champs. L'organisation du code influence les endpoints. Le contrat API reflète l'implémentation, pas le besoin.

Le design-first, c'est l'inverse : le contrat API est écrit avant le code. C'est le contrat qui dicte l'implémentation, pas l'inverse.

Chez DJUST, on a fait ce choix il y a quelques années. Ce billet est un retour d'expérience sur ce que ça implique concrètement.


Pourquoi design-first ?

L'API comme produit

Nos APIs B2B sont consommées par des intégrateurs externes — des partenaires qui construisent des frontends sur notre plateforme, des connecteurs ERP, des outils métier. Pour eux, l'API est le produit. Pas notre code Java. Pas notre architecture interne.

Si notre API change de comportement entre deux versions parce qu'un développeur a refactoré une classe, le partenaire se retrouve à déboguer un problème qu'il n'a pas créé. C'est inacceptable dans un contexte B2B avec des SLAs contractuels.

Le design-first force à penser l'API du point de vue de l'utilisateur avant de coder. C'est une discipline.

La collaboration interdisciplinaire

Chez DJUST, notre PM est capable d'écrire des contrats OpenAPI. Ce n'est pas courant — la plupart des PMs travaillent en prose (user stories, specs fonctionnelles). Le nôtre travaille en YAML.

Ça change fondamentalement la collaboration : le contrat devient le lieu de discussion entre le PM, le Back et le FOC. On ne discute plus de "est-ce que ce champ devrait être obligatoire ?" sur un Notion — on le voit directement dans le YAML, on peut l'ouvrir dans Swagger UI, on peut tester.

Les guidelines LLM

Récemment, notre PM a poussé un cran plus loin : il a publié des guidelines d'écriture de contrat OpenAPI "à la sauce DJUST" dans Notion. L'objectif ? Les passer à un LLM pour générer des contrats standardisés automatiquement.

> "On file ça à notre LLM préféré et il commence à en sortir des contrats mieux standardisés."

C'est la prochaine frontière du design-first : l'IA comme outil de cohérence stylistique sur les contrats.


Le workflow concret chez DJUST

Voici comment on travaille concrètement :

1. Le PM écrit le contrat

Le PM rédige le contrat OpenAPI en YAML, directement dans VSCode, et le pushe sur un repo Git dédié (djustlab/djust-api-contract). Pas de Notion, pas de document Word — du YAML versionné, reviewable, diffable.

2. Le Back implémente

Les développeurs Backend implémentent la feature en prenant le contrat comme référence. Spring Boot génère son propre OpenAPI à partir du code.

3. La vérification

C'est là où ça devenait flou avant. Maintenant, on a un outil de diff : on colle le YAML du PM à gauche, l'URL de l'api-docs du code à droite, et on voit immédiatement les écarts. Descriptions manquantes, types différents, champs renommés — tout apparaît.

4. Le FOC valide

En tant que premier consommateur des APIs, le FOC teste l'implémentation contre le contrat de référence et remonte les problèmes.


Le cas particulier des APIs "cachées"

Il y a un cas de figure intéressant qui révèle quelque chose de fondamental dans l'approche design-first : les APIs purement techniques.

Lors d'une discussion sur un projet récent, on parlait d'une API qui n'allait être exposée que techniquement — pas de documentation publique, pas d'intégrateurs externes, une API utilisée en interne entre services.

La question posée : doit-on quand même appliquer le processus design-first pour cette API ?

Ma réponse :

> "C'est une API qui ne sera exposée que techniquement et on la mettra en caché, donc les devs peuvent la designer comme ils veulent — faudra juste que la QA puisse la tester, donc faudra lui donner le contrat une fois terminé."

C'est une nuance importante. Le design-first n'est pas un rituel dogmatique. C'est un outil au service d'un objectif : garantir que les consommateurs de l'API peuvent travailler de manière autonome.

Pour une API purement interne, les développeurs ont la liberté de conception — ils savent ce qu'ils font. Le seul contrat qu'ils doivent livrer, c'est pour permettre les tests QA. Ce n'est pas la même contrainte qu'une API publique.

Le principe sous-jacent : la rigueur du processus est proportionnelle à la surface d'exposition.


Les défis du design-first

Le design-first n'est pas gratuit. Voici les difficultés réelles :

La dérive du contrat

Sans outil de vérification, le contrat et le code divergent silencieusement. Le développeur fait un refactoring anodin, change un nom de champ, oublie de mettre à jour le YAML. Le contrat devient périmé sans que personne ne s'en rende compte immédiatement.

C'est le problème qu'on a résolu avec l'outil de diff OpenAPI — mais la vraie solution à long terme est l'intégration dans la CI/CD.

Le PM doit savoir écrire du YAML

Notre PM est atypique. La plupart des PMs n'ont ni l'envie ni la compétence pour écrire des contrats OpenAPI. Si votre PM n'est pas technique, le design-first repose sur le Back — et on perd l'avantage de la collaboration interdisciplinaire.

Une solution partielle : les guidelines + LLM. Le PM décrit l'API en langage naturel, le LLM génère le YAML, le Back valide. C'est ce vers quoi on tend.

La résistance au changement

"Ça prend plus de temps." C'est vrai — au départ. Écrire un contrat avant de coder demande un effort upfront. L'argument inverse : combien de temps perd-on à chaque fois qu'un breaking change casse l'intégration d'un partenaire ? Combien de temps de debug évite-t-on quand le contrat est clair dès le départ ?

Le design-first est un investissement, pas un coût.


Ce qu'on a appris

Après quelques années de design-first chez DJUST :

Le contrat comme langue commune. Le YAML OpenAPI est devenu la référence partagée entre le PM, le Back, le FOC et les intégrateurs externes. Quand il y a un désaccord sur le comportement d'une API, on ouvre le contrat — pas une spec Confluence ambiguë.

La documentation n'est pas optionnelle. Avec le design-first, la documentation n'est plus un afterthought — elle est le contrat. Les descriptions des champs, les exemples, les codes d'erreur : tout ça est pensé avant l'implémentation.

La qualité se mesure différemment. On ne dit plus "l'API est terminée quand le code compile". On dit "l'API est terminée quand le contrat est respecté et documenté".


Chetana YIN — Janvier 2026
Engineering Manager chez DJUST. OMS, Payments, Cart.