Оригінальна форма цієї відповіді дико відрізняється, і їх можна знайти тут . Тільки доказ того, що існує кілька способів шкіряти кота.
Я оновив відповідь, оскільки використовував простори імен та використовував 301 переадресацію - а не за замовчуванням 302. Завдяки pixeltrix та Bo Jeanes для підказки щодо цих речей.
Можливо, ви хочете надіти справді міцний шолом, тому що це підірве ваш розум .
API маршрутизації Rails 3 дуже злий. Щоб написати маршрути для вашого API, відповідно до ваших вимог, вам потрібно лише це:
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
Якщо ваш розум залишається неушкодженим після цього моменту, дозвольте мені пояснити.
По-перше, ми називаємо, namespace
що дуже зручно, коли ви хочете купу маршрутів, орієнтованих на певний шлях та модуль, які мають аналогічну назву. У цьому випадку ми хочемо, щоб усі маршрути всередині блоку namespace
були надіслані контролерам в Api
модулі, і всі запити до шляхів всередині цього маршруту будуть встановлені з префіксом api
. Запити, такі як /api/v2/users
, ви знаєте?
Всередині простору імен ми визначаємо ще два простори імен (woah!). На цей раз ми визначаємо в «v1» простір імена, тому всі маршрути для контролерів тут будуть всередині V1
модуля всередині Api
модуля: Api::V1
. Визначивши resources :users
всередині цього маршруту, контролер буде розташований за адресою Api::V1::UsersController
. Це версія 1, і ви потрапляєте туди, роблячи такі запити /api/v1/users
.
Версія 2 - лише трохи крихітна . Замість того, щоб контролер обслуговував його Api::V1::UsersController
, він зараз знаходиться Api::V2::UsersController
. Ви потрапляєте туди, роблячи такі запити /api/v2/users
.
Далі match
використовується a . Це відповідатиме всім маршрутам API, які переходять на такі речі /api/v3/users
.
Це частина, яку мені довелося шукати. Цей :to =>
параметр дозволяє вказати, що конкретний запит слід перенаправляти кудись інше - я це знав дуже багато, - але я не знав, як змусити його перенаправити кудись інше і передати частину оригінального запиту разом з ним .
Для цього ми викликаємо redirect
метод і передаємо йому рядок зі спеціальним інтерпольованим %{path}
параметром. Коли надходить запит, який відповідає цьому фіналу match
, він буде інтерполювати path
параметр у місце розташування %{path}
всередині рядка та перенаправляти користувача туди, куди їм потрібно перейти.
Нарешті, ми використовуємо інший match
для маршрутизації всіх шляхів, що залишилися, з префіксом /api
та перенаправлення на них /api/v2/%{path}
. Це означає, що запити на зразок /api/users
будуть йти /api/v2/users
.
Я не міг розібратися, як домогтися /api/asdf/users
відповідності, бо як визначити, чи повинен це бути запит на /api/<resource>/<identifier>
або /api/<version>/<resource>
?
У будь-якому випадку, це було цікаво для досліджень, і я сподіваюся, що це допоможе вам!