How to Parse JSON Request Body in Sinatra Just Once and Expose It to All Routes

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

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.

Why won't this POST request send a JSON string to the server?

"params" is most likely looking for URL encoded query string values. You want the Body content of the post, not the params.

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

Sharing data between Sinatra condition and request block

Conditions can set instance variables and modify the params hash. For an example, see the built-in user_agent condition.

set(:get_model) { |body| condition { @model = Model.new(body) } }

get '/something', :get_model => something do
"model called #{@model.name}"
end

You should be aware that request is not available at that point, though.

JSON from Javascript Object to Ruby

I believe that if you are sending the JSON in the POST body - you should access it from request.body, and not from params (see this question: How to parse JSON request body in Sinatra just once and expose it to all routes?):

post '/results' do
request.body.rewind
results = JSON.parse(request.body.read, symbolize_names: true)
end

Can I have Sinatra / Rack not read the entire request body into memory?

You cannot avoid this in general without patching Sinatra and/or Rack. It is done by Rack::Request when request.POST is called by Sinatra to create params.

But you could place a middleware in front of Sinatra to remove the body:

require 'sinatra'
require 'stringio'

use Rack::Config do |env|
if env['PATH_INFO'] == '/data' and env['REQUEST_METHOD'] == 'PUT'
env['rack.input'], env['data.input'] = StringIO.new, env['rack.input']
end
end

put '/data' do
while request.env['data.input'].body.read(1024) != nil
# ...
end
# ...
end

opal-jquery ajax request sending malformed json string

After following the advice from this, specifically I'm doing:

before do
request.body.rewind
req = request.body.read
puts req
puts JSON.parse(req)
end

I was able to see that the request arrived at the server correctly and as expected. I don't know why but sinatra was mangling the response in such a away that @params came out as

{"{\"username\":\"some_user\", \"password\":\"some_password\"}"=>nil}

so, in the end I'm doing

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

To read out the request body before sinatra gets anything and just reading out the params I need from @request_payload.

Sinatra: Why are my artists saving to all users and not just the currently logged in user?

It's because of this:

@artists = Artist.all

This loads the full artist list, and that's what you're displaying.

Instead, filter it by the current user:

@artists = current_user.artists


Related Topics



Leave a reply



Submit