Comment gérer les API REST de gestion des versions avec le printemps?

J'ai été à la recherche de la façon de gérer une API REST versions à l'aide de Printemps 3.2.x, mais je n'ai pas trouver quelque chose qui est facile à entretenir. Je vais vous expliquer d'abord le problème que j'ai, et puis une solution... mais je me demande si je suis re-inventer la roue ici.

Je veux gérer la version basée sur l'en-tête Accept, et par exemple, si une demande a l'en-tête Accept application/vnd.company.app-1.1+json, je veux spring MVC transmettre à la méthode qui gère cette version. Et puisque toutes les méthodes de l'API de changement dans le même communiqué, je ne veux pas aller à chacun de mes contrôleurs et de changer quoi que ce soit pour un gestionnaire qui n'a pas changé entre les versions. Aussi, je ne veux pas la logique pour déterminer quelle version utilisée dans le contrôleur eux-mêmes (à l'aide du service des locators), comme le Printemps est déjà la découverte de la méthode à appeler.

Donc pris une API avec les versions 1.0, à 1,8 où un gestionnaire a été introduit dans la version 1.0 et modifié dans la v1.7, je voudrais répondre à ces questions de la manière suivante. Imaginez que le code est à l'intérieur d'un contrôleur, et qu'il y a un code qui est en mesure d'extraire la version de l'en-tête. (Ce qui suit n'est pas valide au Printemps)

@RequestMapping(...)
@VersionRange(1.0,1.6)
@ResponseBody
public Object method1() {
   //so something
   return object;
}

@RequestMapping(...) //same Request mapping annotation
@VersionRange(1.7)
@ResponseBody
public Object method2() {
   //so something
   return object;
}

Ce n'est pas possible au printemps que les 2 méthodes ont la même RequestMapping annotation et le Printemps ne parvient pas à charger. L'idée est que le VersionRange annotation peut définir une version ouverte ou fermée gamme. La première méthode est valable à partir de la version 1.0 à 1.6, tandis que la seconde pour la version 1.7 à partir de (y compris la dernière version 1.8). Je sais que cette approche des pauses si quelqu'un décide de passer de la version à 99,99, mais c'est quelque chose que je suis OK pour vivre avec.

Maintenant, depuis que ci-dessus n'est pas possible sans une sérieuse refonte de la façon dont des travaux du printemps, j'ai pensé à bricoler avec la façon dont les gestionnaires appariés à des demandes, en particulier pour écrire mes propres ProducesRequestCondition, et la version de la gamme là. Par exemple

Code:

@RequestMapping(..., produces = "application/vnd.company.app-[1.0-1.6]+json)
@ResponseBody
public Object method1() {
   //so something
   return object;
}

@RequestMapping(..., produces = "application/vnd.company.app-[1.7-]+json)
@ResponseBody
public Object method2() {
   //so something
   return object;
}

De cette façon, je peux avoir fermé ou ouvert, version plages définies dans le produit une partie de l'annotation. Je suis en train de travailler sur cette solution maintenant, avec le problème que j'avais encore à remplacer certains Spring MVC classes (RequestMappingInfoHandlerMapping, RequestMappingHandlerMapping et RequestMappingInfo), que je n'aime pas, parce que cela signifie un travail supplémentaire à chaque fois que je décide de mettre à niveau vers une version plus récente de printemps.

J'aimerais avoir des pensées... et surtout, une suggestion pour ce faire, dans un système plus simple, plus facile à maintenir façon.


Modifier

L'ajout d'une prime. Pour obtenir la prime, veuillez répondre à la question ci-dessus, sans suggérer d'avoir cette logique dans le contrôleur eux-mêmes. Le printemps a déjà beaucoup de logique pour sélectionner le contrôleur de la méthode à appeler, et je veux greffer sur que.


Edit 2

J'ai partagé l'origine de POC (avec quelques améliorations) sur github: https://github.com/augusto/restVersioning

  • stackoverflow.com/questions/11715874/...
  • Je ne comprends pas votre commentaire. Qui dit simplement que vous pouvez utiliser des en-têtes et, comme je l'ai dit, ce printemps de la boîte n'est pas suffisant pour les Api qui sont mises à jour constamment. Pire encore le lien sur cette réponse utilise la version dans l'URL.
  • Peut-être pas exactement ce que vous cherchez, mais le Printemps 3.2 prend en charge un "produit" paramètre sur RequestMapping. Le seul inconvénient est que la version de la liste doit être explicite. E. g., produces={"application/json-1.0", "application/json-1.1"}, etc
  • oui je sais sur ce paramètre. et vous m'a fait réaliser que j'ai fait une erreur dans la question. Depuis le produit n'a pas d'accepter une gamme de versions, je suis en train d'écrire mon propre ProducesRequestCondition, qui peut comprendre des versions. Comme je l'ai mentionné ci-dessus, afin d'écrire cette classe, j'ai dû réécrire RequestMappingInfoHandlerMapping, RequestMappingHandlerMapping et RequestMappingInfo, parce que RequestMappingInfo est définitive :(.
  • La question/problème ressemble à un doublon pour moi, même si vous en préférez une autre solution de la direction. La accepté de répondre, il vous dit que vous pouvez utiliser des en-têtes, mais d'autres réponses selon le type de contenu permettrait de répondre à la question de trop.
  • Il me semble que vous n'avez pas 9 versions de cette ressource, vous ne disposez que de 2. Je dirais que si vous voulez la version de l'API (il semble que vous n'), puis mettre la version dans l'URI. Si vous voulez la version de la ressource (ou sa représentation) que ce critère se réfère, le mettre dans l'en-tête accept. Je ne recommande pas de faire les deux à la fois, ou il sera se salissant (comme vous l'avez découvert).
  • Nous avons besoin de l'appui de plusieurs versions de notre Api, ces différences sont généralement des modifications mineures qui permettrait de faire quelques appels de certains clients incompatible (il ne sera pas étrange si nous avons besoin de soutien 4 versions mineures, dont certains points sont incompatibles). J'apprécie la suggestion de le mettre dans l'url, mais nous savons que c'est un pas dans la mauvaise direction, que nous avons un couple d'applications avec la version dans l'URL et il y a beaucoup de travail à chaque fois que nous avons besoin de remonter le version.
  • vous fait vous n'avez pas trop. Juste conception de vos changements de l'API manière à ne pas casser la compatibilité ascendante. Juste me donner des exemple des changements que casser la compatibilité et je vous montrer comment faire ces changements dans la non-rupture de la mode.
  • Avez-vous eu un coup d'oeil à stackoverflow.com/a/10336769/2615437 qui semble impliquer que votre déclaration "Ce n'est pas possible au printemps que les 2 méthodes ont la même RequestMapping annotation et le Printemps ne parvient pas à charger." n'est pas totalement correcte?
  • Je n'ai pas vu que. C'est un proche de la solution pour ce que je fais en ce moment (comme j'ai besoin de mon propre condition), mais ça ressemble question plus propre que ma mise en œuvre
  • xwoker vs xworker 🙂
  • Je suis avec Alexey sur celui-ci. Suivez sémantique règles de contrôle de version et de minimiser les modifications de version majeure, et vous n'aurez pas à s'immiscer dans la version plages. Si vous êtes invité à faire une série de rétro-changements incompatibles, vous n'êtes pas à la gestion de votre système de très bien. Je sais que ce n'est pas la réponse que vous cherchez, mais parfois la réponse est de ne pas construire une échelle à l'échelle du 20 pieds du mur, à la fin de la ruelle sombre, mais de se tourner et de retourner à la Rue Principale. 🙂

InformationsquelleAutor Augusto | 2013-11-25