How to parse JSON request body in Sinatra just once and expose it to all routes?

亡梦爱人 提交于 2019-11-27 17:09:16

问题


I am writing an API and it receives a JSON payload as the request body.

To get at it currently, I am doing something like this:

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

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

What's a good way to abstract this away so that I don't need to do it for each route? Some of my routes are more complicated than this, and as a result the request.body would get reread and reparsed several times per route with this approach, which I want to avoid.

Is there some way to make the request_payload just magically available to routes? Like this:

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

回答1:


Use a sinatra before handler:

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

this will expose it to the current request handler. If you want it exposed to all handlers, put it in a superclass and extend that class in your handlers.




回答2:


You can also use Rack Middleware to parse it. See https://github.com/rack/rack-contrib Just use Rack::PostBodyContentTypeParser when initializing your Sinatra class.




回答3:


Like this working for sinatra 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

So you can also symbolize_names while parsing JSON request body, this will give you access to your nested params like this @request_payload[:user]



来源:https://stackoverflow.com/questions/17049569/how-to-parse-json-request-body-in-sinatra-just-once-and-expose-it-to-all-routes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!