2016-02-11 3 views
1

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

Сначала я начал с добавления пространства имен :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_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 в v2 объеме теперь будет установить его в качестве ответа по умолчанию, если версия не запрашивается через заголовки. Я правильно понимаю это? Будет ли лучший подход к обработке версии, чем это? Мысли, идеи, мнения очень ценились.

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

ответ

0

Я использовал тот же 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 

Надеется, что это помогает!