Я мобильщик, пишу на Kotlin, а бэкенд на Rails API поддерживаю сам. Пользователи обновляют приложение месяцами, поэтому старые сборки ходят в API очень долго. Сейчас всё лежит в /api без версии, и каждое изменение формата ответа ломает кого-то на старой сборке. Хочу завести v2 для заказов. Как разложить маршруты и контроллеры, чтобы не копировать всё целиком?
Обычно namespace и наследование контроллеров, копировать нужно только то, что поменялось:
# config/routes.rb
namespace :api do
namespace :v1 do
resources :orders, only: %i[index show create]
end
namespace :v2 do
resources :orders, only: %i[index show create]
end
end
# app/controllers/api/v2/orders_controller.rb
class Api::V2::OrdersController < Api::V1::OrdersController
private
def serialize(order)
OrderSerializer::V2.new(order).as_json
end
end
Выборка и создание остаются в v1, v2 переопределяет только то, как отдать ответ. Старые адреса без версии можно повесить на v1 через scope module: :v1, чтобы старые сборки продолжали ходить туда же. И договорись заранее, когда v1 выключается, например когда на неё приходится меньше двух процентов запросов. Без такой цифры v1 будет жить вечно.
В GraphQL этой боли почти нет: поле помечают deprecated и не удаляют. Но на REST схема с наследованием вполне рабочая
С мобильной стороны совет: пусть приложение шлёт номер сборки в заголовке. Тогда в логах видно, какие сборки ещё живы, и в крайнем случае можно ответить старой сборке 426 с просьбой обновиться, а не молча ломать ей экран заказов.