Версии структуры данных в рельсах - PullRequest
0 голосов
/ 28 июля 2011

Сначала отказ от ответственности: не знаю, пытаюсь ли я здесь невозможное.

Наше приложение rails (2.3.12) растет очень быстро. У маленького жучка уже есть> 20 моделей и> 100 миграций. Одной из задач этого приложения является предоставление API. В настоящее время мы внедряем схему управления версиями API по следующим направлениям: Рекомендации по управлению версиями API? .

Однако, в дополнение к различным версиям контроллеров, мы хотели бы также иметь разные версии таблиц моделей / БД. Например, в версии 1.0 API мы предоставляем метод для получения списка JSON всех автомобилей, скажем, что-то вроде этого:

http://we.com/v1.0/cars/

Для этого у нас есть модель автомобиля (и в соответствии с миграциями), которая выглядит следующим образом:

class car
   attr_accessible :maker, :country
end

Теперь для версии 2 API мы хотим, чтобы наш вызов API выглядел следующим образом:

http://we.com/v2.0/cars

и модель должна выглядеть так:

class car
    attr_accessible :make, :country_code, :country_name
end

Надеюсь, вы поняли картину. Что я не понимаю (или пока не имею правильной идеи):

Нужно ли создавать две модели для работы с использованием пространств имен? Э.Г.

app/models/v1.0/car.rb
app/models/v2.0/car.rb

... или я могу как-то иметь одну модель, которая соответствует версии DATA STRUCTURE? (Примечание: я не собираюсь создавать версии для экземпляров моей модели, vestal_versions и т. Д. Здесь нет решения)

Можно ли использовать две модели одновременно? Я имею в виду, есть ли умный способ использовать обе версии модели на одних и тех же данных? Вспоминаются шаблоны типа «декоратор» или «адаптер», я просто не нашел ни одного примера. Но, учитывая, что у нас был метод конвертера (в нашем примере), который конвертировал бы

[:country] to [:country_code, :country_name]

и наоборот, разве это не сработает?

Возможно ли это? Знаете ли вы драгоценный камень, который занимается этим?

Ответы [ 2 ]

2 голосов
/ 28 июля 2011

Если у вас есть метод преобразования [:country] to [:country_code, :country_name], как вы говорите, я не вижу проблемы. Вам просто нужно убедиться, что контроллеры для каждого из ваших API возвращают правильную вещь.

Я не знаю, как именно вы генерируете свой JSON, но вы могли бы просто написать такие методы, как @car.to_json_1_0 и @car.to_json_2_0 или передать версию в качестве аргумента метода преобразования JSON.

1 голос
/ 28 июля 2011

Я не думаю, что есть решение для такого рода проблем.Я думаю, что лучший способ поддерживать версии API - это сделать:

Создать надежный набор приемочных тестов для всех версий API.(Он должен относиться к вашему API как к черному ящику - не должно быть никаких деталей реализации, таких как имена полей и т. Д.) И это решит вашу проблему - вы сможете изменять детали реализации API старых версий без изменения поведения.Так что в вашем примере, когда вы решите изменить имя поля - ваш набор тестов немедленно покажет вам, что ваш API не работает, и вы должны настроить его реализацию (но не внешнее поведение!).Я думаю, что это было бы на намного проще, чем поддерживать разные версии моделей, которые, я думаю, практически невозможны и излишни.

...