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
Ruby - Determine If a Number Is a Prime
How to Set the Default String Encoding on Ruby 1.9
Are the Date, Time, and Datetime Classes Necessary
(Ruby,Rails) Context of Self in Modules and Libraries...
How to Get the Latest Record from Each Group in Activerecord
Passing Headers and Query Params in Httparty
How to Unfreeze an Object in Ruby
Is There a "Main" Method in Ruby Like in C
How to Display a PDF in Ror (Ruby)
Ruby Dropped in Netbeans 7,How to Use It in Netbeans7
Getting the Highest Value of a Column in Mongodb
Rails 3 Additional Session Configuration Options (Key, Expires_After, Secure)
Rails 6.1, Ruby 3.0.0: Tests Error as They Cannot Load Rexml
Execute a Rake Task from Within Migration
How to Fix Hanging Popen3 in Ruby