La forme originale de cette réponse est très différente et peut être trouvée ici . Juste la preuve qu'il y a plus d'une façon d'écorcher un chat.
J'ai mis à jour la réponse depuis pour utiliser les espaces de noms et utiliser les redirections 301 - plutôt que la valeur par défaut de 302. Merci à pixeltrix et Bo Jeanes pour les invites sur ces choses.
Vous voudrez peut-être porter un casque vraiment solide, car cela va vous épater .
L'API de routage Rails 3 est super méchante. Pour écrire les routes de votre API, conformément à vos exigences ci-dessus, vous avez juste besoin de ceci:
namespace :api do
namespace :v1 do
resources :users
end
namespace :v2 do
resources :users
end
match 'v:api/*path', :to => redirect("/api/v2/%{path}")
match '*path', :to => redirect("/api/v2/%{path}")
end
Si votre esprit est toujours intact après ce point, laissez-moi vous expliquer.
Tout d'abord, nous appelons namespace
ce qui est très pratique lorsque vous voulez un tas de routes étendues à un chemin et un module spécifiques portant le même nom. Dans ce cas, nous voulons que toutes les routes à l'intérieur du bloc pour notre namespace
soient étendues aux contrôleurs dans le Api
module et toutes les demandes aux chemins à l'intérieur de cette route seront préfixées avec api
. Des demandes telles que /api/v2/users
, tu sais?
Dans l'espace de noms, nous définissons deux autres espaces de noms (woah!). Cette fois , nous définissons l'espace de noms « v1 », donc tous les itinéraires pour les contrôleurs ici seront à l' intérieur du V1
module à l' intérieur du Api
module de : Api::V1
. En définissant à l' resources :users
intérieur de cette route, le contrôleur sera situé à Api::V1::UsersController
. C'est la version 1, et vous y arrivez en faisant des requêtes comme /api/v1/users
.
La version 2 est seulement un petit différent bits. Au lieu que le contrôleur le servant soit à Api::V1::UsersController
, il est maintenant à Api::V2::UsersController
. Vous y arrivez en faisant des demandes comme /api/v2/users
.
Ensuite, a match
est utilisé. Cela correspondra à toutes les routes d'API qui vont à des choses comme /api/v3/users
.
C'est la partie que je devais rechercher. L' :to =>
option vous permet de spécifier qu'une demande spécifique doit être redirigée ailleurs - je le savais bien - mais je ne savais pas comment la faire rediriger vers un autre endroit et transmettre un morceau de la demande d'origine avec elle .
Pour ce faire, nous appelons la redirect
méthode et lui passons une chaîne avec un %{path}
paramètre interpolé spécial . Lorsqu'une requête correspond à cette finale match
, elle interpole le path
paramètre à l'emplacement de l' %{path}
intérieur de la chaîne et redirige l'utilisateur vers où il doit aller.
Enfin, nous en utilisons un autre match
pour acheminer tous les chemins restants préfixés par /api
et les rediriger vers /api/v2/%{path}
. Cela signifie que les demandes comme /api/users
iront à /api/v2/users
.
Je ne savais pas comment faire /api/asdf/users
correspondre, car comment déterminer si cela est censé être une demande à /api/<resource>/<identifier>
ou /api/<version>/<resource>
?
Quoi qu'il en soit, c'était amusant de rechercher et j'espère que cela vous aidera!