Версии API Rails

64
9

Я несколько раз искал пару дней, пытаясь выяснить, правильно ли я управляю своими рельсами. Я не нашел хорошего ответа, который помогает мне чувствовать себя комфортно с моим нынешним подходом. Таким образом, я решил перейти к stackoverflow, чтобы узнать мнение моих друзей Rails. Давайте посмотрим на некоторый код:

Сначала я начал с добавления пространства имен :api с субдоменом "api" для моего api в routes.rb. Я также добавил область для v1.

require 'api_constraints'

HostApi::Application.routes.draw do
# Api Definition
namespace :api, defaults: { format: :json }, constraints: { subdomain: 'api' }, path: '/' do
# Scoping Api Version
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
# resources here
end
end
end

Я хочу дать тем, кто ударил api, чтобы вернуть текущую версию по умолчанию, если они не задают другую версию через заголовки. Чтобы справиться с этим, я создал api_constraints в моем каталоге lib.

lib/api_constraints.rb & lib/spec/api_constraints_spec.rb для тестирования.

class ApiConstraints

def initialize(options)
@version = options[:version]
@default = options[:default]
end

def matches?(request)
@default || request.headers["Accept"].include?("application/vnd.host_api.v#{@version}")
end

end

Мой тест проходит, и все чувствует себя хорошо. Мне интересно, когда я начинаю добавлять версию 2,3,4; Могут ли они быть охвачены так же, как v1? Пример:

require 'api_constraints'

HostApi::Application.routes.draw do
# Api Definition
namespace :api, defaults: { format: :json }, constraints: { subdomain: 'api' }, path: '/' do
# Scoping Api Version
scope module: :v1, constraints: ApiConstraints.new(version: 1) do
# resources here
end
scope module: :v2, constraints: ApiConstraints.new(version: 2, default: true) do
# resources here
end
end
end

Я бы предположил, что изменение ApiConstraints по умолчанию true для ApiConstraints в области v2 теперь будет устанавливать его как ответ по умолчанию, когда версия не запрашивается через заголовки. Я правильно понимаю это? Будет ли лучший подход к обработке версии, чем это? Мысли, идеи, мнения очень ценились.

Боковой вопрос. Я также изменил Rails.application.routes.draw в routes.rb на HostApi::Application.routes.draw. Обычно это то, что я видел, другие делают, но я не уверен, что польза от этого. Если бы кто-то мог помочь в разработке, я был бы очень благодарен. Заранее благодарю всех, кто найдет время, чтобы помочь мне понять это или просто поделиться своими мыслями.

спросил(а) 2021-01-25T17:55:53+03:00 4 месяца, 3 недели назад
1
Решение
89

Я использовал те же ApiConstraints в моем ApiConstraints rails-api-base, и он падает при попытке matches? с нестандартной версией без указания заголовка Accept.

Я добавил к моим тестам следующий случай (который падает):

it 'returns false when not default and no Accept header' do
request = double(host: 'api.host_api.dev')
expect(api_constraints_v1.matches?(request)).to be false
end

И я исправил ApiConstraints:

def matches?(req)
@default ||
(req.respond_to?('headers') &&
req.headers.key?('Accept') &&
req.headers['Accept'].include?("application/vnd.host_api.v#{@version}"))
end

Надеюсь, поможет!

ответил(а) 2021-01-25T17:55:53+03:00 4 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема