Подтвердить что ты не робот

Как разобрать тело запроса JSON в Синатре только один раз и разоблачить его на всех маршрутах?

Я пишу API и получает в качестве тела запроса полезную нагрузку JSON.

Чтобы получить в настоящее время, я делаю что-то вроде этого:

post '/doSomething' do
    request.body.rewind
    request_payload = JSON.parse request.body.read

    #do something with request_payload
    body request_payload['someKey']
end

Какой хороший способ отвлечь это, чтобы мне не нужно было делать это для каждого маршрута? Некоторые из моих маршрутов более сложны, чем это, и в результате request.body будет перечитываться и перерисовываться несколько раз на маршрут с помощью этого подхода, чего я хочу избежать.

Есть ли способ сделать request_payload магически доступным для маршрутов? Вот так:

post '/doSomething' do
    #do something with request_payload, it already parsed and available
    body request_payload['someKey']
end
4b9b3361

Ответ 1

Используйте синатра перед обработчиком:

before do
  request.body.rewind
  @request_payload = JSON.parse request.body.read
end

это выведет его на текущий обработчик запросов. Если вы хотите, чтобы он был доступен всем обработчикам, поместите его в суперкласс и расширьте этот класс в обработчиках.

Ответ 2

Вы также можете использовать промежуточное программное обеспечение Rack для его анализа. См. https://github.com/rack/rack-contrib Просто use Rack::PostBodyContentTypeParser при инициализации вашего класса Sinatra.

Ответ 3

Как это работает для синатра 1.4.5

before do
  if request.body.size > 0
    request.body.rewind
    @params = ActiveSupport::JSON.decode(request.body.read)
  end
end

Ответ 4

before do
  request.body.rewind
  @request_payload = JSON.parse(request.body.read, symbolize_names: true)
end

Таким образом, вы также можете использовать symbolize_names при анализе тела запроса JSON, это даст вам доступ к вашим вложенным параметрам, подобным этому @request_payload[:user]