Oryginalna forma tej odpowiedzi jest zupełnie inna i można ją znaleźć tutaj . To tylko dowód, że istnieje więcej niż jeden sposób na oskórowanie kota.
Od tamtej pory zaktualizowałem odpowiedź, aby używać przestrzeni nazw i przekierowań 301 - zamiast domyślnego 302. Dzięki pixeltrix i Bo Jeanes za podpowiadanie tych rzeczy.
Możesz chcieć nosić naprawdę mocny kask, ponieważ to oszaleje .
Interfejs API routingu Rails 3 jest super zły. Aby napisać trasy dla swojego interfejsu API, zgodnie z powyższymi wymaganiami, potrzebujesz tylko tego:
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
Jeśli po tym momencie twój umysł jest nadal nienaruszony, pozwól mi wyjaśnić.
Po pierwsze, wywołujemy, namespaceco jest bardzo przydatne, gdy chcesz, aby grupa tras obejmowała określoną ścieżkę i moduł o podobnej nazwie. W tym przypadku chcemy, aby wszystkie trasy wewnątrz bloku namespacebyły ograniczone do kontrolerów w Apimodule, a wszystkie żądania do ścieżek wewnątrz tej trasy będą poprzedzone prefiksem api. Prośby takie jak /api/v2/users, wiesz?
Wewnątrz przestrzeni nazw definiujemy jeszcze dwie przestrzenie nazw (woah!). Tym razem mamy do definiowania nazw „v1”, więc tutaj wszystkie trasy dla kontrolerów będzie wewnątrz V1modułu wewnątrz Apimodułu: Api::V1. Definiując resources :userswewnątrz tej trasy, kontroler będzie zlokalizowany pod adresem Api::V1::UsersController. To jest wersja 1 i możesz się tam dostać, wykonując żądania, takie jak /api/v1/users.
Wersja 2 jest tylko maleńki nieco inna. Zamiast kontrolera obsługującego to jest Api::V1::UsersControllerteraz, jest teraz Api::V2::UsersController. Dostajesz się tam, składając prośby takie jak /api/v2/users.
Następnie matchużywany jest. Spowoduje to dopasowanie wszystkich tras API, które prowadzą do rzeczy takich jak /api/v3/users.
To jest ta część, na którą musiałem spojrzeć. :to =>Opcja pozwala na określenie, że wniosek powinien zostać przekierowany specyficzny gdzieś indziej - Wiedziałem, że dużo - ale nie wiem jak zrobić to przekierować do innego miejsca i przekazać w kawałku pierwotnego wniosku wraz z nim .
Aby to zrobić, wywołujemy redirectmetodę i przekazujemy jej ciąg znaków ze specjalnym %{path}parametrem interpolowanym . Kiedy przychodzi żądanie, które pasuje do tego końcowego match, interpoluje pathparametr do lokalizacji %{path}wewnątrz ciągu i przekierowuje użytkownika do miejsca, w którym musi się udać.
Na koniec używamy innego matchdo kierowania wszystkich pozostałych ścieżek z prefiksem /apii przekierowywania do nich /api/v2/%{path}. Oznacza to, że żądania takie jak /api/userstrafią do /api/v2/users.
Nie mogłem wymyślić, jak się /api/asdf/usersdopasować, ponieważ jak określisz, czy to ma być prośba o /api/<resource>/<identifier>czy /api/<version>/<resource>?
W każdym razie było to fajne badanie i mam nadzieję, że ci pomoże!