La forma originale di questa risposta è molto diversa e può essere trovata qui . Prova solo che esiste più di un modo per scuoiare un gatto.
Da allora ho aggiornato la risposta per utilizzare gli spazi dei nomi e per utilizzare i reindirizzamenti 301, anziché il valore predefinito 302. Grazie a pixeltrix e Bo Jeanes per il suggerimento su queste cose.
Potresti voler indossare un casco davvero forte perché questo ti lascerà a bocca aperta .
L'API di routing di Rails 3 è super malvagia. Per scrivere i percorsi per l'API, in base ai requisiti sopra indicati, è necessario solo questo:
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
Se la tua mente è ancora intatta dopo questo punto, lasciami spiegare.
In primo luogo, chiamiamo ciò namespace
che è molto utile per quando si desidera un gruppo di route mirate a un percorso e un modulo specifici che hanno un nome simile. In questo caso, vogliamo che tutte le rotte all'interno del blocco namespace
siano indirizzate ai controller all'interno del Api
modulo e tutte le richieste ai percorsi all'interno di questa rotta avranno il prefisso api
. Richieste come /api/v2/users
, sai?
All'interno dello spazio dei nomi, definiamo altri due spazi dei nomi (woah!). Questa volta stiamo definendo lo spazio dei nomi "v1", in modo da tutte le rotte per i controller qui saranno all'interno del V1
modulo all'interno del Api
modulo: Api::V1
. Definendo resources :users
all'interno di questo percorso, il controller si troverà in Api::V1::UsersController
. Questa è la versione 1 e ci si arriva facendo richieste come /api/v1/users
.
La versione 2 è solo una piccola po 'diverso. Invece che il controller che lo sta servendo Api::V1::UsersController
, è ora su Api::V2::UsersController
. Ci si arriva facendo richieste come /api/v2/users
.
Successivamente, match
viene utilizzato a. Questo corrisponderà a tutte le rotte API che vanno a cose del genere /api/v3/users
.
Questa è la parte che ho dovuto cercare. L' :to =>
opzione ti consente di specificare che una specifica richiesta dovrebbe essere reindirizzata da qualche altra parte - lo sapevo molto - ma non sapevo come farla reindirizzare da qualche altra parte e passare un pezzo della richiesta originale insieme ad essa .
Per fare ciò, chiamiamo il redirect
metodo e gli passiamo una stringa con un %{path}
parametro interpolato speciale . Quando arriva una richiesta che corrisponde a questa finale match
, interpolerà il path
parametro nella posizione %{path}
all'interno della stringa e reindirizzerà l'utente dove deve andare.
Infine, ne usiamo un altro match
per instradare tutti i percorsi rimanenti con prefisso /api
e reindirizzarli a /api/v2/%{path}
. Questo significa che richieste come /api/users
andranno a /api/v2/users
.
Non sono riuscito a capire come ottenere la /api/asdf/users
corrispondenza, perché come si determina se si suppone che sia una richiesta /api/<resource>/<identifier>
o /api/<version>/<resource>
?
Ad ogni modo, è stato divertente cercare e spero che ti aiuti!