Pourquoi le versionnage est important
Une API est une promesse. Une fois que des clients en dépendent, toute modification imprudente risque de casser leurs applications, et des clients dont le code est cassé représentent un coût pour tout le monde. Le versionnage est le moyen de déployer des améliorations tout en offrant aux clients un contrat stable et un chemin de migration clair.
L’objectif n’est pas d’éviter le changement, mais de le rendre prévisible : savoir quels changements sont sans risque, exposer les versions de manière cohérente et retirer les anciennes versions selon un calendrier communiqué, plutôt que de prendre les utilisateurs par surprise.
Changements disruptifs (breaking) versus additifs
La majeure partie des difficultés liées au versionnage provient d’un manque de classification des changements. Commencez par établir une règle claire.
Généralement sans risque (additif) :
- Ajouter un nouveau champ optionnel à une réponse.
- Ajouter un nouvel endpoint.
- Ajouter un nouveau paramètre de requête optionnel.
- Ajouter une nouvelle valeur d’enum, si les clients tolèrent les valeurs inconnues.
Disruptif (nécessite une nouvelle version) :
- Supprimer ou renommer un champ.
- Modifier le type ou le format d’un champ.
- Rendre un paramètre optionnel obligatoire.
- Modifier la signification ou la valeur par défaut d’un comportement existant.
- Modifier les codes de statut ou la structure des erreurs dont dépendent les clients.
Concevoir des clients capables d’ignorer les champs inconnus est le meilleur moyen de garantir que les changements additifs restent sans risque. Documentez cette règle pour que personne n’ait à deviner.
Stratégies de versioning
Il existe quatre méthodes courantes pour permettre aux clients de sélectionner une version.
Versioning par URI — la version fait partie du chemin.
GET /v1/posts
GET /v2/posts
C’est visible, facile à router, facile à mettre en cache et facile à tester dans un navigateur. C’est le choix le plus courant pour les API publiques, même si les puristes soutiennent que l’URL ne devrait pas changer.
Versioning par Header — un header personnalisé sélectionne la version.
GET /posts
X-API-Version: 2
Les URLs restent stables, ce qui est avantageux pour la mise en cache par ressource, mais la version est invisible dans les logs, les liens et les tests navigateur.
Versioning par Media-type — la négociation de contenu sélectionne la version.
GET /posts
Accept: application/vnd.example.v2+json
C’est l’approche la plus alignée avec REST et elle s’intègre à la négociation de contenu, mais c’est la plus difficile à découvrir et à déboguer.
Paramètre de requête — ?version=2. Simple, mais facile à oublier et peu pratique pour la mise en cache.
Quelle que soit la méthode choisie, appliquez-la de manière cohérente et documentez-la. Mélanger les stratégies est pire que de choisir une méthode moins tendance.
Dépréciation et retrait (sunset)
La suppression d’une version doit être un processus, et non un événement soudain.
Deprecation: true
Sunset: Wed, 31 Dec 2026 23:59:59 GMT
Link: </v2/posts>; rel="successor-version"
- La dépréciation annonce qu’une version ou un endpoint va disparaître.
- Le retrait (sunset) indique la date exacte à laquelle il cessera de fonctionner.
- Le lien renvoie vers le remplaçant.
Accompagnez ces headers d’un guide de migration, d’entrées dans le changelog et d’une communication directe avec vos utilisateurs intensifs. Surveillez ensuite l’utilisation : si une part significative du trafic utilise encore l’ancienne version à l’approche de la date de retrait, prolongez-la plutôt que de casser ces clients.
Exécuter plusieurs versions en parallèle
Prendre en charge deux versions signifie que le code doit servir les deux. Voici les approches courantes :
- Des handlers versionnés qui pointent vers des services partagés, afin que la logique métier reste centralisée.
- Des adapters qui assurent la traduction entre l’ancienne et la nouvelle représentation.
- Des feature flags pour un déploiement progressif des nouveaux comportements.
- Des specs distinctes par version, générées et publiées aux côtés de l’API.
Veillez à limiter les différences entre les versions. Les bifurcations majeures de la logique sont difficiles à maintenir et risquent rapidement de diverger.
Communiquer les changements
Le versionnage n’est efficace que si les clients savent ce qu’il se passe.
- Publiez un changelog et signalez clairement les changements majeurs (breaking changes).
- Maintenez une OpenAPI spec à jour pour chaque version.
- Envoyez des avis de dépréciation dans les headers et, si possible, par e-mail.
- Fournissez un guide de migration avec des exemples avant/après.
- Prévoyez une période de support adaptée aux cycles de déploiement de vos utilisateurs.
Bonnes pratiques
- Classifiez chaque modification comme additive ou “breaking change” avant le déploiement.
- Privilégiez les modifications additives ; n’incrémentez la version que lorsque c’est indispensable.
- Choisissez une stratégie de versioning et appliquez-la partout.
- Ne supprimez jamais un champ ou un endpoint sans une période de dépréciation.
- Annoncez la dépréciation via des headers et une date de fin de support (sunset date).
- Surveillez le trafic par version avant d’en retirer une.
- Maintenez la logique partagée derrière des adapters spécifiques à chaque version.
Erreurs courantes
- Casser silencieusement les clients en modifiant la structure d’une réponse.
- Versionner chaque modification mineure, créant ainsi une charge de maintenance excessive.
- Mélanger différentes stratégies de versioning au sein d’une même API.
- Supprimer une version sans avertissement préalable ni plan de migration.
- Laisser d’anciennes versions tourner indéfiniment sans stratégie de retrait.
- Oublier de mettre à jour la documentation et les spécifications pour chaque version.
Et après ?
Le versionnage est ce qui permet à une API de survivre à la confrontation avec des clients réels. Appuyez-vous sur une conception REST propre, décrivez chaque version avec OpenAPI et utilisez les en-têtes HTTP pour communiquer les dépréciations. Ensuite, rédigez une politique d’une page pour votre propre API : définissez ce qui constitue un changement majeur (breaking change) et quelle est la durée de vie des versions.