Versioning des API REST. Chaque API a sa propre version

15

Il est très courant de spécifier la version des API REST dans l'URL, spécifiquement au début du chemin, c'est-à-dire quelque chose comme:

POST /api/v1/accounts
GET /api/v1/accounts/details

Cependant, je n'ai vu aucune conception où la version est associée à chaque API. En d'autres termes, nous conservons la version de chaque API séparément. c'est à dire:

POST /api/accounts/v2
GET /api/accounts/details/v3

En utilisant cette approche, nous incrémentons la version API de l'API spécifique lorsque la rupture du changement est nécessaire, pas besoin d'incrémenter la version de l'ensemble des API.

Quels sont les inconvénients de l'utilisation de ce style au lieu du style commun?

Eng.Fouad
la source

Réponses:

13

Ce que vous appelez des API REST uniques peut être appelé un ensemble particulier de ressources ou de ressources de l' API REST . Vous pouvez également le considérer comme les fonctionnalités de l'API REST . Comme tout type de logiciel, l'ensemble du package est versionné / mis à jour, pas des fonctionnalités ou des ressources uniques.

Votre question aurait un sens dans le contexte où les ressources du package API REST sont modulaires et donc potentiellement développées et versionnées séparément.

Ensuite, pour autant que je vois, les principaux inconvénients de la convention de dénomination du localisateur de ressources que vous proposez sont:

  • Pour l' utilisateur de l' API , il en résulterait des localisateurs de ressources beaucoup plus complexes, moins prévisibles, moins mémorables et moins stables.
  • Pour le (s) développeur (s) de module , c'est maintenant plus de travail de devoir gérer ce versioning dans leur propre localisateur de ressources.
  • Les changements dans les localisateurs de ressources deviennent beaucoup plus fréquents, autant qu'il y a plusieurs modules de mise à jour donc les inconvénients ci-dessus sont exponentiels ...

Lors de la construction d'une API, l'un de vos principaux objectifs est de la rendre facile à utiliser ...

Vous pourriez trouver un meilleur moyen d'introduire un changement de rupture ou même de versionner l'API REST avec peut-être un en-tête HTTP?

Pour en savoir un peu plus sur l'approche des en-têtes HTTP, voir les autres réponses ci-dessous et: https://www.troyhunt.com/your-api-versioning-is-wrong-which-is/

ClemC
la source
12

Voici une approche encore meilleure: utilisez la négociation de contenu pour versionner votre API avec les en Content-Type- Accepttêtes et :

POST /api/accounts
Accept: application/vnd.my-api.account.v1+json

201 Created
Location: /api/accounts/285728
Content-Type: application/vnd.my-api.account.v1+json
{ ... account data here ... }

Pour obtenir une version différente, demandez-la simplement avec un type de contenu différent dans Accept. De cette façon, les versions particulières prises en charge par votre serveur sont complètement indépendantes de votre structure URL. Le même serveur peut prendre en charge plusieurs versions en sélectionnant simplement celui avec qui répondre en fonction de l'en- Accepttête. Alternativement, si vous souhaitez vous en tenir à différents déploiements pour différentes versions, vous pouvez mettre un proxy devant différentes versions de votre service qui a choisi celui vers lequel transmettre les demandes en fonction de l'en- Accepttête.

Cela vous permet également de prendre en charge de nouveaux formats avec des sémantiques différentes (pas seulement des versions différentes) sur les mêmes points de terminaison. Par exemple, POSTER une liste de comptes /api/accountspourrait signifier la création de lots, et vous n'auriez pas besoin de créer un point de terminaison API distinct pour cela.

Jack
la source
omg l'en-tête accept doit être le pire choix de signalisation de version. utilisez un en-tête de version si vous le pouvez, un chemin d'URL si vous le devez (c.-à-d. le routage AWS)
Ewan
@Ewan Pourquoi? Un en-tête de version personnalisé implique que différentes versions sont la même ressource sans informer les intermédiaires que le contenu peut être différent. Un proxy de mise en cache ne saurait pas utiliser votre en-tête pour ne pas servir les réponses v1 mises en cache aux demandes v2.
Jack
utilisez l'en-tête de réponse variable, si vous n'utilisez pas déjà no-cache pour les demandes d'api !. le type de contenu a déjà un sens, le suborning pour votre usage privé rend la vie difficile aux consommateurs
Ewan
@Ewan C'est à cela que servent la vndpartie et la +syntaxe du type: pour indiquer qu'il s'agit d'un sous-type spécifique au fournisseur du application/jsontype. C'est exactement pour cela que les types de contenu sont conçus. Votre ressource est disponible en plusieurs formats. Vous demandez au client de choisir le format qu'il souhaite. De plus, il n'y a aucune raison pour que les demandes d'API ne puissent pas utiliser la sémantique de mise en cache HTTP standard.
Jack
si vous corrigez un bogue dans myapi v2, vous ne retournez pas de nouveau type mime.
Ewan
5

L'essentiel est que si vous versionnez chaque point de terminaison séparément, vous devez pouvoir déployer chaque point de terminaison séparément.

Les API ont généralement une seule version car tous les points de terminaison sont dans la même base de code et ont donc des dépendances partagées et sont déployés ensemble.

Si vous ne mettez pas à jour la version lorsque vous effectuez une modification, car "Oh, je suis sûr que ma modification n'affecte pas cela", vous aurez des problèmes lorsque vous faites une erreur.

De plus, vous souhaiterez déployer simultanément les versions v1 et v2 de votre API. Cela se fait normalement en déployant chaque version sur un serveur distinct et en acheminant le trafic en conséquence.

Si vous n'avez pas de version d'API unique, cela devient beaucoup plus complexe.

Ewan
la source