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
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.
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.
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
来源:https://stackoverflow.com/questions/17049569/how-to-parse-json-request-body-in-sinatra-just-once-and-expose-it-to-all-routes