Как разобрать тело запроса 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
Ответы
Ответ 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]