Управление версиями API: кто должен осуществлять диспетчеризацию на основе версий?
Я разрабатываю API с использованием ruby и Sinatra для уже существующего приложения Rails. Я разделил приложения (без логики монтирования), и поэтому они развертываются отдельно. На производстве я использую nginx в качестве прокси-сервера для обоих приложений, который использует сопоставление доменов для отправки в нужное приложение.
Я также версионирую свой API. В настоящее время я делаю это в самом приложении Sinatra, перезаписывая методы, которые вызывают, публикуют, вызывают фильтры и т. Д., Поэтому, какие бы правила строк или регулярных выражений вы ни применяли для соответствия запросу uri, они будут иметь Версионирование перед ними добавлено:
# matches /v0.1/resource/:id
get "/resource/:id" ....
у этого недостатка является то, что он всегда должен соответствовать по крайней мере началу URL, сначала / включенному, иначе номер версии не будет добавлен правильно. Мало того, это означает, что я также сопоставляю только одну версию API для каждого приложения.
Я все еще работаю над первой версией, поэтому пришло время выяснить, как лучше двигаться дальше по мере того, как происходит изменение версии API. Я вижу две возможные стратегии:
Сделайте все это в духе Rails (как они рекомендуют в Railscast для остальных версий API) и постоянно сопоставляйте версии в приложении:
get "/0.1/resource/:id" do ..... get "/0.2/resource/:id" do .....
у этого недостатка всегда есть две (или более) версии логики, что делает логику сопоставления URL более сложной (например, если я хочу сопоставить все с одним правилом, например /\d+/resource/\d+, тогда я буду Я все еще должен увидеть, является ли номер версии приемлемым) и увеличить общее количество случаев появления спагетти, на мой взгляд.
его преимущество заключается в том, что он поддерживает ту же логику развертывания (замените последнюю версию текущей, nginx направляет только один API и т. д.).
Пусть nginx рассылает по версии. Используя CVS, я могу создать версию своего кода. Мне просто нужно определить, сколько его версий я бы хотел поддерживать в сети, развернуть их, а затем изменить порядок маршрутизации nginx, который теперь будет основан на домене и версии.
Это имеет преимущество в очистке логики приложения, поскольку я сопоставляю только необходимые правила для логики. используя последний пример:
get "/resource/:id" do ....
и nginx позаботится о маршрутизации к нужному приложению.
у этого есть несколько технических недостатков: чтобы это работало, мне придется изменить стратегию развертывания, так как мне нужно выбрать, сколько версий API я поддерживаю, извлечь их из моего CVS, затем отредактировать конфигурацию nginx, удалить последние правила API, вставьте новые (путь к api.myapp.com/v1, api.myapp.com/v2...) и переинициализируйте nginx. Другой недостаток заключается в том, что теперь мне нужно поддерживать более одной основы кода API, например, для исправления ошибок... которая аналогична приведенной выше, мне просто нужно поддерживать другую основу кода с тегами версий.
Я хотел бы знать, как другие решили эту проблему в своих случаях, и как это повлияло на последующее обслуживание.