Bonnes pratiques de versionnage d'API, pour les appelants
8 min de lecture
Le versionnage d’API est la pratique de garder fonctionnel un ancien contrat après l’avoir changé, pour que les appelants puissent avancer selon leur propre calendrier plutôt que le vôtre. Cette phrase contient les deux décisions qui comptent : ce qui compte comme changer le contrat, et combien de temps l’ancien continue de fonctionner. Où vit le numéro de version, sujet de la plupart des débats de versionnage, est la moins importante des trois et la plus facile à réussir.
Quand devrait-on versionner une API ?
Versionnez une API seulement quand un changement casserait un appelant correct. Les changements additifs, nouveaux champs, nouveaux endpoints, nouveaux paramètres optionnels, n’ont pas besoin de version ; les appelants écrits contre l’ancien contrat continuent de fonctionner et la nouvelle capacité est simplement là. Un changement cassant en a besoin, parce que l’alternative est qu’un appelant l’apprenne par une erreur. Versionner chaque release, y compris les additives, apprend aux appelants que les versions sont du bruit, et ils cessent de lire les avis qui comptent.
Le test pratique est celui de l’article sur les changements cassants : si un appelant qui ne comptait que sur le comportement documenté doit changer quelque chose pour continuer à fonctionner, le changement a besoin d’une version. Sinon, livrez-le sous la version actuelle et écrivez une entrée de changelog.
Quel schéma de versionnage d’API devrait-on utiliser ?
Utilisez le schéma que vos appelants peuvent voir et fixer le plus facilement, ce qui pour la plupart des API publiques est une version dans le chemin de l’URL ou un en-tête de version daté. Les quatre schémas courants diffèrent moins en capacité qu’en ce qu’ils demandent à l’appelant, et c’est la bonne base pour choisir.
| Schéma | Exemple | Ce que l’appelant doit faire | Qui l’utilise |
|---|---|---|---|
| Chemin URL | /v2/invoices | Changer l’URL en migrant | La plupart des API REST publiques |
| En-tête de version | X-GitHub-Api-Version: 2022-11-28 | Envoyer un en-tête, ou accepter le défaut | GitHub |
| Version de compte datée | Stripe-Version: 2026-08-26 | Fixer une date par requête ou par compte | Stripe |
| Paramètre de requête | /invoices?version=2 | Ajouter un paramètre | API plus anciennes ; rarement choisi maintenant |
| Type de média | Accept: application/vnd.example.v2+json | Négocier les types de contenu | Puristes ; peu d’appelants maîtrisent |
Chemin URL est le plus visible et le moins flexible. Chaque appelant peut voir dans quelle version il se trouve en lisant une ligne de log, et un saut de version est un chercher-remplacer. Le coût : toute la surface bouge d’un coup, vous ne pouvez pas changer le contrat d’un seul endpoint sans frapper une nouvelle version pour tous, donc les versions de chemin tendent à être rares et volumineuses.
En-tête de version garde les URL stables et laisse le serveur choisir un défaut pour les
appelants qui n’envoient rien, comme fonctionne le
versionnage de l’API REST de GitHub :
une version nommée par date dans X-GitHub-Api-Version, avec la version supportée la plus ancienne
comme défaut pour que les appelants non versionnés ne cassent pas. Le coût : la version est
invisible dans une URL et facile à oublier dans un nouveau client.
Version de compte datée est le schéma d’en-tête plus un ajout : la version est stockée contre
le compte, donc chaque requête l’obtient sans rien envoyer. Le
versionnage d’API de Stripe fixe chaque compte à la
version avec laquelle il a été créé et laisse une requête l’écraser avec Stripe-Version. C’est le
schéma le plus favorable à l’appelant et celui qui demande le plus de travail à opérer, parce que
le serveur doit traduire entre chaque version supportée et l’actuelle. Le fonctionnement détaillé
est dans le versionnage de l’API Stripe.
Paramètre de requête et type de média fonctionnent tous les deux et échouent tous les deux le test de visibilité de manière différente : un paramètre de requête se perd facilement en construisant une URL, et une version en type de média est invisible pour presque tout outil avec lequel un appelant déboguerait.
Comment fait-on le versionnage d’API en pratique ?
En pratique, une version est un ensemble nommé de comportements, et le serveur mappe chaque requête sur l’un d’eux. Les étapes sont les mêmes quel que soit le schéma qui porte le nom.
- Nommez les versions par date ou par entier, pas par version sémantique. Une API web n’est
pas un paquet. Les appelants ne peuvent pas fixer une version mineure d’une URL, donc
v2ou2026-08-26dit tout ce dont un appelant a besoin, et le versionnage sémantique implique une promesse de compatibilité que le schéma ne peut pas tenir. - Gardez la version hors des chemins de code qui s’en fichent. Une version devrait sélectionner une couche de traduction en bordure, pas bifurquer la logique métier. Deux copies complètes de la codebase, c’est comment une version finit non maintenue.
- Donnez à chaque version un défaut et un document. Les appelants qui n’envoient pas de version reçoivent la plus ancienne supportée, jamais la plus récente, pour qu’un client non fixé ne casse pas le jour de la release. Chaque version a une page qui dit ce qui a changé par rapport à la précédente.
- Fixez une fenêtre de support et publiez-la. Le guide de versionnage de Google, AIP-185, demande une période de transition raisonnable et bien communiquée, et recommande 180 jours même pour une fonctionnalité bêta. Choisissez une fenêtre, écrivez-la, et appliquez-la sans renégocier par version.
- Retirez les versions comme vous retirez les endpoints. Une version passé sa fenêtre reçoit
le même traitement que toute API dépréciée : une annonce, un
en-tête
Sunset(RFC 8594) sur chaque réponse, un rappel à mi-chemin aux appelants restants, et une date de suppression qui tient.
Que sont v1 et v2 dans une API REST ?
v1 et v2 sont des noms pour deux contrats que le même serveur supporte en même temps. Un v2
existe parce que quelque chose dans v1 ne pouvait pas être changé sans casser ses appelants,
donc le changement est allé dans un nouveau contrat et l’ancien a continué de fonctionner. Les
numéros n’impliquent pas que v2 est complet ou que v1 est mort ; les deux ne sont vrais que si
la documentation le dit. Un v3 qui apparaît chaque trimestre est un signe que des changements
additifs sont versionnés, ou que le contrat n’a jamais été conçu pour absorber le changement. gRPC
résout le même problème différemment : changements d’API gRPC et Protobuf
couvre le versionnage via le nom de package dans un fichier .proto plutôt qu’un chemin d’URL, et
un format sur le fil où renommer un champ est gratuit mais le renuméroter est un changement
cassant qu’aucun appelant REST ne reconnaîtrait comme risqué.
Que devrait annoncer un changement de version ?
Un changement de version devrait annoncer ce qui casse, qui ça concerne, comment migrer, et combien de temps la version précédente continue de fonctionner. L’entrée a la même forme que n’importe quelle autre entrée de changement cassant, plus une ligne indiquant la fenêtre de support. En voici une pour une API versionnée par en-tête :
La version d’API 2026-11-01 est disponible. La version 2025-06-15 est supportée jusqu’au 1er novembre 2027. Nouveau dans 2026-11-01 :
GET /invoicesrenvoieamounten unités minimales comme entier plutôt que comme chaîne décimale, et le champ dépréciécustomer_nameest supprimé au profit de l’objetcustomer. Concerne les appelants sur 2025-06-15 qui parsentamountcomme chaîne, ce qui est le défaut pour les clients non fixés créés avant juin 2025. Migration : parsezamountcomme entier et lisez le nom depuiscustomer.name. FixezX-Api-Version: 2026-11-01quand vous êtes prêt. Rien ne change pour les appelants qui ne fixent pas de version.
La dernière phrase est celle qui laisse la plupart des lectrices arrêter de lire, et elle appartient à chaque annonce de version. La page exemples de changelog inclut des entrées d’API qui versionnent ainsi, et la différence entre les bonnes et le reste tient surtout dans cette dernière phrase.
Qui est prévenu quand une version change ?
Tout le monde sur l’ancienne version, individuellement, et le changelog pour tous les autres. Un changement de version est le seul cas où “on a posté quelque chose à ce sujet” manque garantiment exactement les appelants qui comptent : ceux qui ont fixé une version il y a deux ans et n’ont pas lu de note de release depuis. Les données d’usage répondent qui ils sont ; l’avis doit les atteindre là où est leur code, dans les en-têtes de réponse et dans un message à la propriétaire du compte.
Dans la boucle qu’on exécute, l’entrée qui annonce une version est rédigée à partir de la pull request qui la livre, relue par une personne, et publiée sur feed et widget, où un client versionné peut la lire en JSON. Toute personne dont le retour via le widget a demandé le changement, ou signalé le bug qu’elle résout, et est devenu une issue GitHub que la pull request ferme, est prévenue sur cette issue dès que l’entrée est publiée. Le mécanisme est le même que pour n’importe quelle entrée ; un saut de version n’est que l’entrée avec l’enjeu le plus élevé.
FAQ
Chaque changement d’API devrait-il obtenir une nouvelle version ? Non. Seulement les changements cassants. Les changements additifs sont livrés sous la version actuelle avec une entrée de changelog. Versionner les changements additifs apprend aux appelants à ignorer les versions.
Le versionnage par URL est-il meilleur que par en-tête ? Le versionnage par URL est plus facile à voir pour les appelants et plus difficile à faire évoluer petit à petit pour vous ; le versionnage par en-tête est l’inverse. Pour une API publique avec beaucoup de petits clients, le versionnage par URL échoue moins. Pour une grande API avec couche de traduction, la version datée par en-tête passe mieux à l’échelle.
Combien de versions devraient être supportées à la fois ? Le moins possible selon votre fenêtre de support, et jamais un nombre illimité. Deux ou trois versions concurrentes est normal ; plus que ça signifie généralement que les versions ne sont pas retirées.
Que devraient recevoir les requêtes non versionnées ? La version supportée la plus ancienne, pour que les clients existants non fixés continuent de fonctionner, avec un en-tête de réponse leur disant quelle version ils ont reçue.
Les affirmations techniques de cet article n'ont pas été vérifiées de façon indépendante. Si quelque chose est faux, dis-le-nous et nous le corrigerons.