53 votes

Versionnage de l'API REST (ne versionner que la représentation, pas la ressource elle-même)

J'ai jeté un coup d'œil à Pratiques recommandées pour la versioning des API ?, mais je ne suis pas tout à fait convaincu de la réponse, donc je remets en question la partie sur la version avec un exemple plus spécifique. J'ai deux URI (une avec la version comme partie de l'URI et une sans) :

http://xxxx/v1/user/123    -> solution privilégiée dans le fil de discussion
http://xxxx/user/123             

J'ai des doutes quant à savoir si le premier lien exprime l'idée de REST. Je trouve http://xxxx/v1/user/123 déroutant car cela suggère qu'il y aura une version d'API supérieure un jour comme http://xxxx/v2/user/123. Mais cela n'a pas de sens en termes de REST, la version de l'API elle-même est HTTP 1.0 ou 1.1, qui est déjà envoyée dans la requête HTTP. Cette vue centrique des ressources REST diffère beaucoup des autres API comme SOAP ou les interfaces Java (où il est courant d'avoir des versions d'API dans les noms qualifiés).

En REST, la seule chose où la versioning a du sens est la représentation de cette ressource (par exemple, de nouveaux champs sont ajoutés ou supprimés). Ce versioning fait partie de la négociation de contenu comme :

http://xxx/user/123 + En-tête HTTP 'Accept' -> Négociation de contenu via l'en-tête
http://xxx/user/123?v=1                    -> pour les liens permanents/hyperliens

On pourrait aussi arguer que cette négociation de contenu par version pourrait faire partie de l'URI à l'intérieur du chemin, mais je trouve cela contre-intuitif, car vous pourriez vous retrouver avec des URI différentes pour la même ressource et devoir gérer des redirections à un moment donné.

Pour résumer : Dans les URI REST, il n'y a pas de versioning de l'API, seulement du versioning de la représentation de la ressource. Les informations de version de la représentation relèvent de la négociation de contenu (comme queryParam ou l'en-tête HTTP 'Accept').

Qu'en pensez-vous ? Sur quels points seriez-vous en désaccord/d'accord ?

1 votes

Just one little thing to add. the only showstopper to me and to use the ...v1/ style is, when you haven't got the load-balancing under control and can't define directions to the app-servers on HTTP header basis on the frontmachines (-> content-negotiation is part of the HTTP-header). Often the standard is to use the URL path. and in the web-frameworks I can think of it is difficult to define the request-mapping endpoints inside controller on HTTP-header basis instead of the path.

38voto

Stefan Tilkov Points 1253

Je suis tout à fait d'accord; une URI exprime l'identité, l'identité ne change pas lorsque une nouvelle version est introduite. Il peut y avoir de nouvelles URIs pour des concepts supplémentaires, bien sûr, et les URIs existantes peuvent rediriger ... mais inclure un "v2" dans l'URI me semble relever du RPC.

Notez que cela n'a vraiment rien à voir avec REST, car d'un point de vue REST, ce ne sont que des caractères.

2 votes

Oui, ce ne sont que des caractères. mais il est bon d'avoir des URIs jolies/cohérentes, car elles font partie de l'interface avec laquelle les utilisateurs de l'API programment.

1 votes

Voici un autre bon exemple de la façon de ne pas utiliser de version dans votre URL, blog.steveklabnik.com/2011/07/03/…

1 votes

Cela a été répondu en détail auparavant ici stackoverflow.com/q/389169/104261.

11voto

yfeldblum Points 42613

Vous pourriez écouter un en-tête de requête HTTP X-API-Version. Si l'en-tête existe, alors le serveur doit utiliser cette version de l'API. Si l'en-tête n'existe pas, le serveur peut utiliser la dernière version de l'API.

> GET /user/123 HTTP/1.1
> Host: xxx
> X-API-Version: >=1.5.1, <2.0.0
> Accept: application/json
>

< HTTP/1.1 200 OK
< X-API-Version: 1.6.12
<
< { "user": { "id": 123, "name": "Bob Smith" } }
<

0 votes

Mais cela ne souffre-t-il pas du risque que divers intermédiaires (proxys, caches) puissent ou non respecter cette en-tête et ne la transmettent même pas ?

0 votes

Peut-être - cela dépendrait certainement du proxy.

0 votes

Dommage que les en-têtes soient supprimés dans certains cas.

9voto

Darrel Miller Points 56797

Pour ce que ça vaut, je suis d'accord avec toi Manuel. Vous pouvez voir mon raisonnement dans cette question Comment versionner les URIs REST

Il y a beaucoup de gens qui semblent ne pas être d'accord mais je ne m'inquiéterais pas. À quoi ressemble votre URL n'a pas vraiment un impact important sur votre client tant que vous respectez la contrainte de l'hypertexte.

2 votes

+1 "Ce à quoi ressemble votre URL n'a vraiment pas un grand impact sur votre client tant que vous respectez la contrainte d'hypertexte". Cela ne peut pas être suffisamment souligné.

0 votes

+1 pour "Ce que votre url ressemble vraiment n'a pas un grand impact sur votre client tant que vous respectez la contrainte hypertexte"

2voto

cdent Points 51

Je suis d'accord que vous ne voulez pas voir les versions dans les URI des ressources présentées dans votre API. Cela les rend pas "cool". Je suis également d'accord que ce sont les représentations qui sont les plus susceptibles de changer.

Cependant, cela soulève alors la question de ce qui se passe lorsque vous modifiez le contenu d'une représentation particulière. Par exemple, si votre représentation JSON initiale d'un frobnitz est

{"x": "bam", "y": "hello"}

et que vous souhaitez ajouter un champ "z", vous pouvez considérer que le client devrait être conscient que nous sommes maintenant sur la version 2 d'un certain type de schéma de données.

Je ne suis pas sûr de cela. Je pense que vous avez quelques options :

  • Permettez à vos clients d'être flexibles face à des représentations évoluant doucement. Dans l'exemple ci-dessus, nous générons toujours un dictionnaire JSON.
  • Si nécessaire, incluez une version dans la représentation elle-même (un champ de version dans cet exemple). En procédant ainsi, vous déclarez effectivement une sous-représentation dans le type de contenu JSON. Cependant, je pense que cela est assez limitant.
  • Utilisez vos propres types MIME et donnez-leur une version : application/x-my-special-json1.0, application/x-my-special-json1.1. Cela vous permet de versionner vos représentations de manière indépendante les unes des autres. Encore une fois, avec cette approche, vous demandez beaucoup à vos clients pour qu'ils comprennent ce qu'il se passe.

En général, je pense que vous voulez optimiser votre API et vos représentations pour des clients que vous n'avez pas vous-même inventés ; ceux que d'autres personnes créeront en découvrant vos ressources. Je pense que c'est utile même dans le cas où vous créez quelque chose de privé car cela intègre une contrainte de conception utile qui contribuera à rendre votre système plus robuste.

1voto

Mr-sk Points 5604

Je trouve http://xxxx/v1/user/123 confus car cela suggère qu'il y aura une version d'api plus élevée à l'avenir comme http://xxxx/v2/user/123

Ce n'est pas ce que cela suggère - cependant vous avez cette possibilité dans le futur.

Mais cela n'a pas de sens en termes de REST, la version de l'api est elle-même HTTP 1.0 ou 1.1, qui est déjà envoyée dans la requête HTTP.

La version DE VOTRE API et la version d'HTTP que vous utilisez pour faire des requêtes n'ont pas besoin d'être égales.

On pourrait aussi argumenter que cette négociation de contenu de version pourrait faire partie de l'URI dans le chemin, mais je trouve que cela est contre-intuitif, car vous pourriez vous retrouver avec des URIs différentes pour la même ressource et devoir maintenir des redirections à un moment donné.

Il est correct d'avoir la version en tant que paramètre d'URI comme vous l'avez démontré.

http://xxx/user/123?v=1 -> pour des liens permanents/hypertextes

0 votes

Merci pour les indices. mais une question : en termes REST, qu'est-ce qui, à votre avis, fait une version de 'VOTRE API'? car je ne vois pas simplement une version à l'intérieur d'une application REST en dehors du protocole HTTP et de la représentation de la ressource.

4 votes

Je commence généralement les API REST à partir de la v1. La version de l'API est essentiellement un contrat/interface sur lequel les clients peuvent s'accorder. Si je modifie l'interface/API, et peut-être que je casse ce contrat, je pourrais passer à une v2 ou v1.1 - Cependant, aucune de mes raisons pour la version n'est liée à la version du client HTTP effectuant la demande. Est-ce que cela vous aide?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X