Оригинальная форма этого ответа дико отличается, и можно найти здесь .Просто доказательство того, что существует более одного способа шкурить кошку.
Я обновил ответ с тех пор, чтобы использовать пространства имен и использовать перенаправления 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
, знаете ли?
Внутри пространства имен мы определяем еще два пространства имен (вау!).На этот раз мы определяем пространство имен «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
.Это будет соответствовать всем маршрутам 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>
?
В любом случае, это было интересно исследовать, и я надеюсь, что это поможет вам!