В настоящее время я занимаюсь разработкой версионного API для нового веб-сайта.Я понимаю, как использовать пространство имен для маршрутов, но я застрял в наилучшем способе реализации версионных методов в модели.
В примерах кода ниже используется структура rails, но принцип работы должен быть согласован в большинстве веб-сайтов.frameworks.
Маршруты в настоящее время выглядят примерно так:
MyApp::Application.routes.draw do
namespace :api do
namespace :v1 do
resources :products, :only => [:index, :show]
end
end
end
И контроллер:
class Api::V1::ProductsController < V1Controller
respond_to :json, :xml
def index
respond_with @products = Product.scoped
end
def show
respond_with @product = Product.find(params[:id])
end
end
Итак, очевидно, мы просто выставляем атрибуты, доступные в Product здесьЭто решение прекрасно работает, если у вас будет только одна версия API.Что происходит, когда вы хотите выпустить V2, а V2 необходимо переопределить способ отображения имени продукта (при сохранении обратной совместимости с V1 - по крайней мере, в краткосрочной перспективе)?
Насколько я понимаю, у вас естьпара опций ...
- Немедленно прекратить поддержку V1 и справиться с последствиями (наихудшее из возможных решений)
- Вы начинаете переопределять методы to_ [format] (я довольноконечно, вы делаете это с помощью as_ [format], но это не имеет значения) для добавления нового атрибута ...
name_2
- это выглядит одинаково глупо - Реализация некоторого прокси-класса, который отвечает за показ толькометоды, которые мы ищем
- Позволяет представлениям создавать какой-то хэш, который контролируются версионными контроллерами и вызывают
to[format]
on ...
Три и четыре - единственные, которыеЯ могу думать, что в этом есть какой-то смысл ... Три будут выглядеть примерно так:
# model
class Api::V1::Product < Struct.new(:product)
def to_json
attributes.to_json
end
def to_xml
attributes.to_xml
end
private
def attributes
{:name => product.name} # add all the attributes you want to expose
end
end
# Controller
class Api::V1::ProductsController < V1Controller
respond_to :json, :xml
def show
respond_with @product = Api::V1::Product.new(Product.find(params[:id]))
end
end
Что делали другие люди в прошлом?