web-dev-qa-db-fra.com

Comment version REST URI

Quel est le meilleur moyen de créer la version REST des URI? Actuellement, nous avons un numéro de version dans l'URI lui-même, c'est-à-dire.

http://example.com/users/v4/1234/

pour la version 4 de cette représentation.

La version appartient-elle à la chaîne de requête? c'est à dire.

http://example.com/users/1234?version=4

Ou est-ce que la gestion des versions est plus efficace autrement?

103
Mike Pone

Je dirais que faire partie de l'URI lui-même (option 1) est préférable, car la v4 identifie une ressource différente de la v3. Les paramètres de requête, comme dans votre deuxième option, peuvent être utilisés au mieux pour transmettre des informations supplémentaires (requête) relatives à request plutôt qu'à resource.

30
Zef Hemel

Ne pas modifier les URL, car ... 

  • tu casses des permaliens
  • Les modifications d'URL se propagent comme une maladie via votre interface. Que faites-vous avec des représentations qui n’ont pas changé mais qui pointent vers la représentation qu’elle a? Si vous modifiez l'URL, vous cassez d'anciens clients. Si vous quittez l’URL, vos nouveaux clients risquent de ne pas fonctionner.
  • La gestion des types de supports est une solution beaucoup plus flexible.

En supposant que votre ressource renvoie une variante de application/vnd.votresociété.user + xml, il vous suffit de créer un support pour un nouveau type de média application/vnd.votre.société.userV2 + xml Les clients v2 peuvent coexister pacifiquement.

Dans une interface RESTful, l'élément le plus proche d'un contrat est la définition des types de média échangés entre le client et le serveur.

Les URL que le client utilise pour interagir avec le serveur doivent être fournies par le serveur incorporé dans les représentations précédemment récupérées. La seule URL à connaître par le client est l'URL racine de l'interface. L'ajout de numéros de version à des URL n'a de valeur que si vous construisez des URL sur le client, ce que vous n'êtes pas censé faire avec une interface RESTful.

Si vous devez modifier vos types de médias pour casser vos clients existants, créez-en un nouveau et laissez vos URLs!

Et pour les lecteurs qui disent actuellement que cela n’a aucun sens si j’utilise application/xml et application/json comme types de média. Comment sommes-nous censés les mettre en version? Tu n'es pas. Ces types de média sont quasiment inutiles pour une interface RESTful à moins que vous ne les analysiez en utilisant le téléchargement de code, auquel cas le contrôle de version est un point discutable.

191
Darrel Miller

Ah, je remets mon vieux chapeau grincheux.

Du point de vue de ReST, cela n’a aucune importance. Pas un saucisson.

Le client reçoit un URI qu'il souhaite suivre et le traite comme une chaîne opaque. Mettez tout ce que vous voulez dedans, le client a no connaissance d'une chose telle qu'un identifiant de version.

Ce que le client sait, c'est qu'il peut traiter le type de média, et je conseillerai de suivre les conseils de Darrel. De plus, j'estime personnellement que le fait de devoir modifier à quatre reprises le format utilisé dans une architecture reposante devrait générer d'énormes signes avant-coureurs indiquant que vous faites quelque chose de grave, et contourner complètement la nécessité de concevoir votre type de support pour la résilience au changement.

Quoi qu'il en soit, le client ne peut traiter un document que dans un format compréhensible et suivre les liens qu'il contient. Il faut savoir sur les relations de lien (les transitions). Donc, ce qui est dans l'URI est complètement hors de propos.

Personnellement, je voterais pour http: // localhost/3f3405d5-5984-4683-bf26-aca186d21c04

Un identifiant parfaitement valide qui empêchera tout développeur client ou personne touchant le système de se demander si on devrait mettre v4 au début ou à la fin d'un URI (et je suggère que, du point de vue du serveur, vous ne devriez pas avoir 4 versions, mais 4 types de supports).

21
SerialSeb

Vous ne devez PAS mettre la version dans l'URL, mais la version dans l'en-tête Accepter de la demande - voir mon post sur ce fil de discussion:

Les meilleures pratiques pour la gestion des versions API?

Si vous commencez à coller des versions dans l'URL, vous vous retrouvez avec des URL stupides comme celles-ci: http://company.com/api/v3.0/customer/123/v2.0/orders/4321/

Et il y a beaucoup d'autres problèmes qui se glissent aussi - voir mon blog: http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html

11
jeremyh

Ces questions SO (moins spécifiques) sur le contrôle de version de l'API REST peuvent être utiles:

5
Pete TerMaat

Je voulais créer des API versionnées et j'ai trouvé cet article très utile:

http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http

Il y a une petite section sur "Je veux que mon API soit versionnée". Je l'ai trouvé simple et facile à comprendre. Le point crucial consiste à utiliser le champ Accepter dans l'en-tête pour transmettre les informations de version.

2
Asma Zubair

Si les services REST nécessitent une authentification avant utilisation, vous pouvez facilement associer la clé/le jeton d'API à une version d'API et effectuer le routage en interne. Pour utiliser une nouvelle version de l'API, une nouvelle clé d'API peut être requise, liée à cette version.

Malheureusement, cette solution ne fonctionne que pour les API basées sur les autorisations. Cependant, il garde les versions hors des URI.

2
UberSteve

Si vous utilisez des URI pour la gestion des versions, le numéro de version doit figurer dans l'URI de la racine de l'API afin que chaque identificateur de ressource puisse l'inclure.

Techniquement, une API REST ne divise pas les modifications d'URL (résultat de la contrainte d'interface uniforme). Il ne fonctionne que lorsque la sémantique associée (par exemple, un vocabulaire spécifique à une API RDF) change de manière non compatible avec la version antérieure (rare). Actuellement, de nombreuses personnes n'utilisent pas de liens pour la navigation (contrainte HATEOAS) ni de vocabulaire pour annoter leurs réponses REST (contrainte de message auto-descriptive), c'est pourquoi leurs clients font une pause.

Les types MIME personnalisés et la gestion des versions de type MIME ne sont d'aucune aide, car l'insertion des métadonnées associées et de la structure de la représentation dans une chaîne courte ne fonctionne pas. Ofc. les métadonnées et la structure changeront fréquemment, ainsi le numéro de version aussi ... 

Donc, pour répondre à votre question, la meilleure façon d’annoter vos requêtes et vos réponses avec des mots ( Hydra , données liées ) et d’oublier la gestion des versions ou de l’utiliser uniquement avec des modifications de vocabulaire non compatibles remplacer un vocabulaire par un autre).

1
inf3rno

J'inclurais la version en tant que valeur facultative à la fin de l'URI. Cela peut être un suffixe comme/V4 ou un paramètre de requête comme vous l'avez décrit. Vous pouvez même rediriger le/V4 vers le paramètre de requête afin de prendre en charge les deux variantes. 

1
Paul Morgan

Je vote pour cela en mime mais pas en URL ..__ Mais la raison n’est pas la même que celle des autres gars.

Je pense que l'URL devrait être unique (à l'exception de ces redirections) pour localiser la ressource unique . Donc, si vous acceptez /v2.0 dans les URL, pourquoi ne s'agit-il pas de /ver2.0 ou /v2/ ou /v2.0.0? Ou même -alpha et -beta? (alors cela devient totalement le concept de semver )

Ainsi, la version en type mime est plus acceptable que l'URL.

0
Yarco

Il existe 4 approches différentes pour la gestion des versions de l'API:

  • Ajout de version au chemin de l'URI:

    http://example.com/api/v1/foo
    
    http://example.com/api/v2/foo
    

    Lorsque vous avez un changement important, vous devez incrémenter la version telle que: v1, v2, v3 ... 

    Vous pouvez implémenter un contrôleur dans votre code comme ceci:

    @RestController
    public class FooVersioningController {
    
    @GetMapping("v1/foo")
    public FooV1 fooV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping("v2/foo")
    public FooV2 fooV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • Demander le contrôle de version des paramètres:

    http://example.com/api/v2/foo/param?version=1
    http://example.com/api/v2/foo/param?version=2
    

    Le paramètre version peut être facultatif ou requis selon l'utilisation souhaitée de l'API.

    L'implémentation peut ressembler à ceci:

    @GetMapping(value = "/foo/param", params = "version=1")
    public FooV1 paramV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping(value = "/foo/param", params = "version=2")
    public FooV2 paramV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • Passage d'un en-tête personnalisé:

    http://localhost:8080/foo/produces
    

    Avec en-tête:

    headers[Accept=application/vnd.company.app-v1+json]
    

    ou:

    headers[Accept=application/vnd.company.app-v2+json]
    

    Le principal avantage de ce schéma est principalement la sémantique: vous ne surchargez pas l’URI avec quoi que ce soit qui concerne le contrôle de version.

    Mise en oeuvre possible:

    @GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v1+json")
    public FooV1 producesV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v2+json")
    public FooV2 producesV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • Changer de nom d’hôte ou utiliser une passerelle API:  

    Pour l’essentiel, vous déplacez l’API d’un nom d’hôte à un autre. Vous pourriez même simplement appeler cette construction une nouvelle API pour les mêmes ressources. 

    Vous pouvez également le faire en utilisant des passerelles API.

0
Javier C.