La forme originale de cette réponse est très différente et peut être trouvée ici. . C'est la preuve qu'il y a plus d'une façon d'écorcher un chat.
J'ai mis à jour la réponse depuis, afin d'utiliser les espaces de noms et les redirections 301 - plutôt que la redirection 302 par défaut. Merci à pixeltrix et à Bo Jeanes pour avoir insisté sur ces points.
Vous pourriez vouloir porter un vraiment un casque solide parce que ça va épatez votre esprit .
L'API de routage de Rails 3 est super géniale. Pour écrire les routes pour 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 encore intact après ce point, laissez-moi vous expliquer.
D'abord, nous appelons namespace
ce qui est très pratique lorsque l'on veut avoir un tas de routes ayant une portée sur un chemin spécifique et un module qui ont un nom similaire. Dans ce cas, nous voulons que toutes les routes à l'intérieur du bloc pour notre module namespace
pour qu'il soit adapté aux contrôleurs dans le cadre de l'initiative Api
et toutes les requêtes vers les chemins à l'intérieur de cette route seront préfixées avec api
. Des demandes telles que /api/v2/users
tu sais ?
À l'intérieur de l'espace de noms, nous définissons deux autres espaces de noms (woah !). Cette fois, nous définissons l'espace de noms "v1", donc toutes les routes pour les contrôleurs seront dans l'espace de noms "v1". V1
à l'intérieur du module Api
module : Api::V1
. En définissant resources :users
à l'intérieur de cet itinéraire, le contrôleur sera situé à Api::V1::UsersController
. C'est la version 1, et vous y arrivez en faisant des requêtes telles que /api/v1/users
.
La version 2 n'est qu'une petit un peu différent. Au lieu que le contrôleur qui le sert soit à Api::V1::UsersController
il est maintenant à Api::V2::UsersController
. Vous y arrivez en faisant des demandes comme /api/v2/users
.
Ensuite, un match
est utilisé. Cela correspondra à toutes les routes API qui vont vers des choses comme /api/v3/users
.
C'est la partie que j'ai dû chercher. Le site :to =>
vous permet de spécifier qu'une requête spécifique doit être redirigée vers un autre endroit - je le savais déjà - mais je ne savais pas comment faire pour qu'elle soit redirigée vers un autre endroit et transmettre un morceau de la requête originale en même temps.
Pour ce faire, nous appelons le redirect
et lui transmettre une chaîne de caractères avec une valeur de %{path}
paramètre. Lorsqu'une demande arrive et qu'elle correspond à ce paramètre final match
il interpolera le path
dans l'emplacement de %{path}
à l'intérieur de la chaîne et redirige l'utilisateur vers l'endroit où il doit aller.
Enfin, nous utilisons une 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
ira à /api/v2/users
.
Je n'arrivais pas à trouver comment obtenir /api/asdf/users
de correspondre, car comment déterminer si c'est censé être une demande de /api/<resource>/<identifier>
o /api/<version>/<resource>
?
Quoi qu'il en soit, cette recherche a été amusante et j'espère qu'elle vous aidera !