C'est une bonne et une question délicate. Le sujet de la conception d'URI est en même temps la partie la plus importante d'une API REST et , par conséquent, un engagement potentiellement à long terme envers les utilisateurs de cette API .
Étant donné que l'évolution d'une application et, dans une moindre mesure, son API est une réalité et qu'elle est même similaire à l'évolution d'un produit apparemment complexe comme un langage de programmation, la conception de l' URI devrait avoir moins de contraintes naturelles et elle devrait être préservée au fil du temps . Plus la durée de vie de l'application et de l'API est longue, plus l'engagement envers les utilisateurs de l'application et de l'API est important.
D'un autre côté, une autre réalité est qu'il est difficile de prévoir toutes les ressources et leurs aspects qui seraient consommés via l'API. Heureusement, il n'est pas nécessaire de concevoir l'intégralité de l'API qui sera utilisée jusqu'à Apocalypse . Il suffit de définir correctement tous les points d'extrémité de ressource et le schéma d'adressage de chaque ressource et instance de ressource.
Au fil du temps, vous devrez peut-être ajouter de nouvelles ressources et de nouveaux attributs à chaque ressource particulière, mais la méthode que les utilisateurs d'API suivent pour accéder à des ressources particulières ne devrait pas changer une fois qu'un schéma d'adressage de ressource devient public et donc définitif.
Cette méthode s'applique à la sémantique des verbes HTTP (par exemple, PUT doit toujours mettre à jour / remplacer) et aux codes d'état HTTP qui sont pris en charge dans les versions d'API antérieures (ils doivent continuer à fonctionner pour que les clients d'API qui ont travaillé sans intervention humaine puissent continuer à fonctionner). comme ça).
De plus, étant donné que l'intégration de la version de l'API dans l'URI perturberait le concept d' hypermédia en tant que moteur de l'état de l'application (indiqué dans la thèse de doctorat de Roy T. Fieldings) en ayant une adresse de ressource / URI qui changerait avec le temps, je conclurais que l' API les versions ne doivent pas être conservées pendant longtemps dans les URI de ressources, ce qui signifie que les URI de ressources sur lesquels les utilisateurs d'API peuvent compter doivent être des permaliens .
Bien sûr, il est possible d'incorporer la version d'API dans l'URI de base, mais uniquement pour des utilisations raisonnables et restreintes comme le débogage d'un client d'API qui fonctionne avec la nouvelle version d'API. Ces API versionnées devraient être limitées dans le temps et disponibles pour des groupes limités d'utilisateurs d'API (comme pendant les versions bêta fermées) uniquement. Sinon, vous vous engagez là où vous ne devriez pas.
Quelques réflexions sur la maintenance des versions d'API qui ont une date d'expiration. Toutes les plates-formes / langages de programmation couramment utilisés pour implémenter des services Web (Java, .NET, PHP, Perl, Rails, etc.) permettent de lier facilement les points d'extrémité de service Web à un URI de base. De cette façon, il est facile de rassembler et de conserver une collection de fichiers / classes / méthodes séparées entre les différentes versions d'API .
À partir du POV des utilisateurs d'API, il est également plus facile de travailler avec une version d'API particulière et de s'y lier lorsque cela est évident, mais uniquement pour une durée limitée, c'est-à-dire pendant le développement.
À partir du POV du mainteneur d'API, il est plus facile de maintenir différentes versions d'API en parallèle en utilisant des systèmes de contrôle de source qui fonctionnent principalement sur des fichiers comme la plus petite unité de version (code source).
Cependant, avec les versions d'API clairement visibles dans l'URI, il y a une mise en garde: on pourrait également s'opposer à cette approche car l' historique des API devient visible / apparenté dans la conception de l'URI et est donc sujet à des changements au fil du temps, ce qui va à l'encontre des directives de REST. Je suis d'accord!
La façon de contourner cette objection raisonnable est d'implémenter la dernière version d'API sous l'URI de base d'API sans version. Dans ce cas, les développeurs de clients API peuvent choisir:
développer contre la dernière (en s'engageant à maintenir l'application en la protégeant des éventuels changements d'API qui pourraient casser leur client d'API mal conçu ).
se lier à une version spécifique de l'API (qui devient apparente) mais uniquement pour une durée limitée
Par exemple, si l'API v3.0 est la dernière version d'API, les deux suivantes doivent être des alias (c'est-à-dire se comporter de manière identique pour toutes les demandes d'API):
http: // shonzilla / api / clients / 1234
http: // shonzilla / api /v3.0 / clients / 1234
http: // shonzilla / api / v3 / customers / 1234
De plus, les clients d'API qui tentent toujours de pointer vers l' ancienne API doivent être informés de l'utilisation de la dernière version d'API précédente, si la version d'API qu'ils utilisent est obsolète ou n'est plus prise en charge . Donc, accéder à l'un des URI obsolètes comme ceux-ci:
http: // shonzilla / api /v2.2 / customers / 1234
http: // shonzilla / api /v2.0 / customers / 1234
http: // shonzilla / api / v2 / customers / 1234
http: // shonzilla / api /v1.1 / customers / 1234
http: // shonzilla / api / v1 / customers / 1234
doit renvoyer l'un des codes d'état HTTP 30x qui indiquent la redirection utilisée en conjonction avec l' Location
en-tête HTTP qui redirige vers la version appropriée de l'URI de ressource qui reste celle-ci:
http: // shonzilla / api / clients / 1234
Il existe au moins deux codes d'état HTTP de redirection appropriés pour les scénarios de version d'API:
301 Déplacé de manière permanente indiquant que la ressource avec un URI demandé est déplacée de manière permanente vers un autre URI (qui doit être un permalien d'instance de ressource qui ne contient pas d'informations de version d'API). Ce code d'état peut être utilisé pour indiquer une version d'API obsolète / non prise en charge, informant le client API qu'un URI de ressource versionné a été remplacé par un permalien de ressource .
302 Trouvé indiquant que la ressource demandée se trouve temporairement à un autre emplacement, alors que l'URI demandé peut toujours être pris en charge. Ce code d'état peut être utile lorsque les URI sans version sont temporairement indisponibles et qu'une demande doit être répétée en utilisant l'adresse de redirection (par exemple en pointant vers l'URI avec la version APi intégrée) et que nous voulons dire aux clients de continuer à l'utiliser (c'est-à-dire le permaliens).
d'autres scénarios peuvent être trouvés dans le chapitre Redirection 3xx de la spécification HTTP 1.1
410 Gone
, car une redirection pourrait indiquer que le nouvel emplacement est compatible lorsqu'il ne l'est pas. Si l'API est simplement obsolète mais existe toujours, unWarning
en-tête HTTP sur la réponse peut être une option.L'URL ne doit PAS contenir les versions. La version n'a rien à voir avec "l'idée" de la ressource que vous demandez. Vous devriez essayer de penser à l'URL comme étant un chemin vers le concept que vous souhaitez - pas comment vous voulez que l'article soit retourné. La version dicte la représentation de l'objet, pas le concept de l'objet. Comme d'autres affiches l'ont dit, vous devez spécifier le format (y compris la version) dans l'en-tête de la demande.
Si vous regardez la requête HTTP complète pour les URL qui ont des versions, cela ressemble à ceci:
L'en-tête contient la ligne qui contient la représentation que vous demandez ("Accepter: application / xml"). C'est là que la version devrait aller. Tout le monde semble ignorer le fait que vous souhaitiez peut-être la même chose dans différents formats et que le client devrait pouvoir demander ce qu'il veut. Dans l'exemple ci-dessus, le client demande TOUTE représentation XML de la ressource - pas vraiment la vraie représentation de ce qu'il veut. Le serveur pourrait, en théorie, renvoyer quelque chose de complètement indépendant de la demande tant qu'il s'agissait de XML et il faudrait l'analyser pour réaliser qu'il est incorrect.
Une meilleure façon est:
De plus, disons que les clients pensent que le XML est trop verbeux et qu'ils veulent maintenant JSON à la place. Dans les autres exemples, vous devrez avoir une nouvelle URL pour le même client, vous vous retrouverez donc avec:
(ou quelque chose de similaire). Quand en fait, chaque requête HTTP contient le format que vous recherchez:
En utilisant cette méthode, vous avez beaucoup plus de liberté dans la conception et adhérez en fait à l'idée originale de REST. Vous pouvez changer de version sans perturber les clients ou changer les clients de manière incrémentielle à mesure que les API sont modifiées. Si vous choisissez d'arrêter de prendre en charge une représentation, vous pouvez répondre aux demandes avec un code d'état HTTP ou des codes personnalisés. Le client peut également vérifier que la réponse est au bon format et valider le XML.
Il existe de nombreux autres avantages et j'en discute certains ici sur mon blog: http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html
Un dernier exemple pour montrer comment mettre la version dans l'URL est mauvais. Disons que vous voulez des informations à l'intérieur de l'objet et que vous avez versionné vos différents objets (les clients sont v3.0, les commandes sont v2.0 et l'objet shipto est v4.2). Voici l'URL désagréable que vous devez fournir au client:
la source
-x
car il est déconseillé par RFC6648 .Nous avons trouvé pratique et utile de mettre la version dans l'URL. Il vous permet de savoir facilement ce que vous utilisez en un coup d'œil. Nous faisons des alias / foo à / foo / (dernières versions) pour la facilité d'utilisation, des URL plus courtes / plus propres, etc., comme le suggère la réponse acceptée.
Garder la compatibilité descendante pour toujours est souvent prohibitif et / ou très difficile. Nous préférons donner un avis avancé de dépréciation, des redirections comme suggéré ici, des documents et d'autres mécanismes.
la source
Je suis d'accord que la version de la représentation des ressources suit mieux l'approche REST ... mais, un gros problème avec les types MIME personnalisés (ou les types MIME qui ajoutent un paramètre de version) est le mauvais support pour écrire dans les en-têtes Accept et Content-Type en HTML et JavaScript.
Par exemple, il n'est pas possible IMO de POST avec les en-têtes suivants dans les formulaires HTML5, afin de créer une ressource:
En effet, l'
enctype
attribut HTML5 est une énumération, donc autre chose que l'habituelapplication/x-www-formurlencoded
,multipart/form-data
ettext/plain
n'est pas valide.... et je ne suis pas sûr qu'il soit pris en charge par tous les navigateurs en HTML4 (qui a un attribut encytpe plus laxiste, mais serait un problème d'implémentation du navigateur quant à savoir si le type MIME a été transféré)
Pour cette raison, je pense maintenant que le moyen le plus approprié pour la version est via l'URI, mais j'accepte que ce ne soit pas la manière «correcte».
la source
Mettez votre version dans l'URI. Une version d'une API ne prend pas toujours en charge les types d'une autre, donc l'argument selon lequel les ressources sont simplement migrées d'une version à une autre est tout simplement faux. Ce n'est pas la même chose que de passer du format XML à JSON. Les types peuvent ne pas exister ou ils peuvent avoir changé sémantiquement.
Les versions font partie de l'adresse de ressource. Vous routez d'une API à une autre. Il n'est pas RESTful de masquer l'adressage dans l'en-tête.
la source
Il y a quelques endroits où vous pouvez faire du versioning dans une API REST:
Comme indiqué, dans l'URI. Cela peut être maniable et même esthétique si les redirections et similaires sont bien utilisées.
Dans l'en-tête Accepts:, la version est donc dans le type de fichier. Comme «mp3» vs «mp4». Cela fonctionnera également, bien que l'OMI, cela fonctionne un peu moins bien que ...
Dans la ressource elle-même. De nombreux formats de fichiers ont leur numéro de version intégré, généralement dans l'en-tête; cela permet aux logiciels plus récents de «fonctionner simplement» en comprenant toutes les versions existantes du type de fichier, tandis que les logiciels plus anciens peuvent se lancer si une version non prise en charge (plus récente) est spécifiée. Dans le contexte d'une API REST, cela signifie que vos URI ne doivent jamais changer, juste votre réponse à la version particulière des données qui vous a été remise.
Je peux voir les raisons d'utiliser les trois approches:
la source
Le contrôle de version de votre API REST est analogue au contrôle de version de toute autre API. Des changements mineurs peuvent être effectués sur place, des changements majeurs peuvent nécessiter une toute nouvelle API. Le plus simple pour vous est de recommencer à zéro à chaque fois, c'est quand il est plus logique de mettre la version dans l'URL. Si vous voulez simplifier la vie du client, vous essayez de maintenir la compatibilité descendante, ce que vous pouvez faire avec la dépréciation (redirection permanente), les ressources dans plusieurs versions, etc. Ceci est plus fastidieux et nécessite plus d'efforts. Mais c'est aussi ce que REST encourage dans «Les URI cool ne changent pas».
Au final, c'est comme n'importe quelle autre conception d'API. Pesez l'effort contre la commodité du client. Envisagez d'adopter le contrôle de version sémantique pour votre API, ce qui montre clairement à vos clients à quel point votre nouvelle version est rétrocompatible.
la source