Переключение функций Sinatra API

суть

Можно ли внедрить функцию переключения функций в приложение Sinatra?

На всякий случай немного о переключении функций ;)

Предыстория

Я создал модульный проект Sinatra и стремлюсь реализовать конечную точку GET/POST/PUT/DELETE для всех своих ресурсов; это упрощает тестирование приложения и управление данными во время разработки.

Проблема

Когда я приступаю к работе, я не хочу, чтобы существовали ненужные конечные точки (например, DELETE '/users').

Вопрос

Могу ли я аннотировать методы каким-то флагом :development или, может быть, перехватить запрос в блоке before? Сделали бы вы это с помощью помощника? Я не уверен, что иду по правильному пути, возможно, я слишком усложняю (?)

Как бы это сделать?

Если вы сделали что-то подобное, было бы здорово, если бы вы могли поделиться своими открытиями со всей нацией.


person MrHaze    schedule 27.09.2015    source источник


Ответы (1)


Вы можете использовать текущую среду, чтобы решить, определяете ли вы действие. Например:

class MyApp < Sinatra::Application
  if settings.development?
    get '/admin' do
      'VIPs only'
    end
  end
end

Если у вас есть много переключателей, вы можете изолировать их в одном файле, который вы можете решить требовать или нет:

# routes/init.rb
require_relative 'main'
require_relative 'debug' if settings.development?
# routes/main.rb
class MyApp < Sinatra::Application
  get '/' do
    'Hello!'
  end
end
# routes/debug.rb
class MyApp < Sinatra::Application
  get '/admin' do
    'VIPs only'
  end
end

Или, если вы хотите перечислить свои пути только для разработки в одном месте, вот версия фильтра:

class MyApp < Sinatra::Application
  DEVELOPMENT_PATHS = %w[
    /admin
  ]

  before do
    unless settings.development? || !DEVELOPMENT_PATHS.include?(request.path)
      halt 404 
    end
  end
end

Затем вы также можете создать некоторые методы, подобные декоратору, которые добавляются в список:

class MyApp < Sinatra::Application
  def self.development_only(path)
    DEVELOPMENT_PATHS << path
  end

  get '/admin' do
    'VIPs only'
  end
  development_only '/admin
end

В целом, я бы рекомендовал проявлять осторожность при введении существенных различий между кодом, который выполняется в процессе разработки, и в рабочей среде. Неизбежно, код разработчика либо остается непроверенным, либо становится громоздким для правильной поддержки. В этом случае есть опасность, что вы пропустите маршрут, который намеревались скрыть, и он станет доступным для всех в рабочей среде. Я бы предпочел вообще не иметь этих маршрутов и манипулировать своей средой разработки с консоли или пройти весь путь до конца и создать полностью протестированные и готовые к эксплуатации разрешения пользователей с помощью чего-то вроде sinatra-authentication.

person Kristján    schedule 27.09.2015
comment
Спасибо за исчерпывающий ответ. Я использую аутентификацию, думаю, мне не нужно скрывать конечные точки, если я проверяю учетные данные администратора, но я все же подумал, что еще один уровень инкапсуляции был бы хорош. Какой из трех методов, которые вы показали выше, вы бы порекомендовали? - person MrHaze; 28.09.2015
comment
Я бы предпочел изолировать все в файле debug, так как он очень четко показывает, что предназначено только для разработчиков, и полностью исключает производство кода с помощью одного переключателя. Мне не нравится оператор if для каждого маршрута только потому, что у вас будет так много разбросанных вокруг. Если у вас есть куча разных маршрутов отладки в файлах, которые вы организуете по ресурсам (пользователи, сообщения и т. д.), тогда я бы выбрал версию декоратора. - person Kristján; 28.09.2015
comment
Спасибо за это, у меня была такая же идея насчет каждого маршрута if, он мог запутаться. - person MrHaze; 28.09.2015