Contrôle de version api REST (uniquement la version de la représentation, pas la ressource elle-même)

J’ai jeté un oeil sur les meilleures pratiques pour la gestion des versions d’API? , mais je ne suis pas tout à fait convaincu de la réponse, je me pose donc la question de la version avec un exemple plus spécifique. J’ai deux adresses URI (une avec gestion des versions dans le cadre de l’URI et une sans):

http://xxxx/v1/user/123 -> favored solution in discussed thread http://xxxx/user/123 

Je doute que le premier lien exprime l’idée de REST. Je trouve http://xxxx/v1/user/123 confus car cela suggère qu’il y aura une version supérieure de l’API comme http://xxxx/v2/user/123 . Mais cela n’a aucun 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 centrée sur les ressources REST est très différente des autres interfaces api telles que les interfaces SOAP ou Java (où il est courant d’avoir des versions d’API dans des noms qualifiés).

Au moment du REST, la seule chose où le contrôle de version a un 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 + HTTP 'Accept' Header -> Content negotation through header http://xxx/user/123?v=1 -> for perma-links/hyperlinks 

On pourrait également faire valoir qu’une telle version de la négociation de contenu pourrait faire partie de l’URI dans le chemin, mais je la trouve contre-intuitive, car vous pourriez vous retrouver avec des URI différents pour la même ressource et maintenir les redirections à un moment donné.

En résumé: dans les URI REST, il n’y a pas de version-api, uniquement le versionnage de la représentation de la ressource. La version-info de la représentation appartient à la négociation de contenu (comme queryParam ou HTTP ‘Accept’).

Qu’est-ce que tu penses? Dans quelles choses seriez-vous en désaccord / d’accord?

Je suis complètement d’accord; un URI exprime l’identité, l’identité ne change pas lorsqu’une nouvelle version est introduite. Il pourrait y avoir de nouveaux URI pour des concepts supplémentaires, bien sûr, et les URI existants pourraient redirect… mais l’inclusion d’un “v2” dans l’URI me sent RPCish.

Notez que cela n’a rien à voir avec REST, vraiment, car, du sharepoint vue de REST, ce ne sont que des caractères.

Vous pouvez écouter un en X-API-Version tête de requête HTTP X-API-Version . Si l’en-tête existe, 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" } } < 

Pour ce que ça vaut, je suis d’accord avec toi Manuel. Vous pouvez voir mon raisonnement dans cette question Comment mettre à jour les URI REST

Il y a beaucoup de gens qui semblent en désaccord mais je ne m’inquièterais pas. Ce à quoi ressemble votre url n’a pas d’impact majeur sur votre client tant que vous respectez la contrainte hypertexte.

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”. Convenez également que ce sont les représentations les plus susceptibles de changer.

Cependant, il 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 originale d’un frobnitz est

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

et vous voulez append un champ “z”, vous pouvez avoir le sentiment que le client doit savoir que nous sums maintenant sur la version 2 d’un schéma de données.

Je ne suis pas certain de ça. Je pense que vous avez quelques options:

  • Faites en sorte que vos clients soient flexibles face aux représentations qui changent en douceur. Dans l’exemple ci-dessus, nous continuons à générer un dictionnaire JSON.
  • Si vous devez, mettez une version dans la représentation elle-même (un champ de version dans cet exemple). Ce faisant, vous déclarez efficacement une sous-représentation dans le type de contenu JSON. Je pense que c’est assez limitant cependant.
  • Utilisez vos propres types MIME et mettez-les en version: application / x-my-special-json1.0, application / x-my-special-json1.1. Cela vous permet de mettre à jour vos représentations indépendamment les unes des autres. Encore une fois, avec celui-ci, vous demandez beaucoup à vos clients de savoir ce qui se passe.

En général, je pense que vous souhaitez optimiser votre API et vos représentations pour les clients que vous n’avez pas inventés vous-même; celles que d’autres personnes créeront en découvrant vos ressources. Je pense que cela est utile même lorsque vous créez quelque chose de privé car il crée une contrainte de conception utile qui rendra votre système plus robuste.

Je trouve http: // xxxx / v1 / user / 123 confus car cela suggère qu’il y aura une version supérieure de l’API comme http: // xxxx / v2 / user / 123

Cela ne suggère pas que – cependant vous avez cette capacité dans le futur.

Mais cela n’a aucun 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.

La version de VOTRE API et la version de HTTP que vous utilisez pour effectuer des requêtes ne doivent pas nécessairement être égales.

On pourrait également faire valoir qu’une telle version de la négociation de contenu pourrait faire partie de l’URI dans le chemin, mais je la trouve contre-intuitive, car vous pourriez vous retrouver avec des URI différents pour la même ressource et maintenir les redirections à un moment donné.

C’est bien d’avoir la version comme paramètre d’URI comme vous l’avez démontré.

http: // xxx / user / 123? v = 1 -> pour les liens perma / hyperliens

Une autre approche pourrait consister à dire que “une représentation a plusieurs API”:

 http://xxx/user/123/api/1.json 

Et si vous le souhaitez, vous pouvez retourner la représentation en utilisant la dernière API lorsque vous demandez comme ceci:

 http://xxx/user/123.json 

Personnellement, j’aime mieux les autres solutions mais c’est une autre approche que je n’ai pas encore vue suggérer ici.

Pour REST, la plupart des réponses sont l’élément de données. Je suppose que les API à plusieurs versions partagent toujours la même couche de données. Cela signifie que la couche de données vous oblige à penser de manière rétrocompatible. Les gros changements à effectuer ne sont possibles que si votre API change de manière rétrocompatible. En pratique, cela signifie que des propriétés supplémentaires sont ajoutées silencieusement à vos entités tout en utilisant la dépréciation par date dans votre document API pour indiquer quand quelque chose sera supprimé. Idéalement, vous utilisez un schéma de registre avec l’adresse électronique de vos utilisateurs de clé API, afin que vous puissiez les informer de la déchéance dans un certain domaine (à la page Facebook).