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ò namespaceche è 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 namespacesiano indirizzate ai controller all'interno del Apimodulo 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 V1modulo all'interno del Apimodulo: Api::V1. Definendo resources :usersall'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, matchviene 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 redirectmetodo e gli passiamo una stringa con un %{path}parametro interpolato speciale . Quando arriva una richiesta che corrisponde a questa finale match, interpolerà il pathparametro nella posizione %{path}all'interno della stringa e reindirizzerà l'utente dove deve andare.
Infine, ne usiamo un altro matchper instradare tutti i percorsi rimanenti con prefisso /apie reindirizzarli a /api/v2/%{path}. Questo significa che richieste come /api/usersandranno a /api/v2/users.
Non sono riuscito a capire come ottenere la /api/asdf/userscorrispondenza, 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!