Reading Parameters on Sinatra Post

reading parameters on Sinatra post

Sinatra just doesn't parse this data, because they are not form parameters.

Form parameter would look like this

curl -X POST 127.1:4567/ -d "foo=bar"

Instead of params you can just use request.body.read or use rack contrib.

rack-contrib

  1. Install it with gem install rack-contrib
  2. require it

require 'rack'

require 'rack/contrib'


  1. load it use Rack::PostBodyContentTypeParser

with this you can use params as normal for json post data. Something like this:

curl -X POST -H "Content-Type: application/json" -d '{"payload":"xyz"}' 127.1:4567/

source for this: Sinatra controller params method coming in empty on JSON post request, http://jaywiggins.com/2010/03/using-rack-middleware-to-parse-json/

Read parameters via POST with Ruby + Sinatra + MongoDB

Solution:

You should apply a JSON.parse and then read parameter

code

post '/post/?' do
params = JSON.parse request.body.read
puts params['name']
end

Sinatra, retrieve only post parameters

Accessing the request object directly gives you a simple way of accessing post data, much like the php $_POST variable:

post '/' do
request.POST.inspect # instead of params.inspect
end

More info on the Rack request object here: http://rack.rubyforge.org/doc/classes/Rack/Request.html#M000274

How do I read unknown post data with Sinatra?

You can iterate over the entries in a Hash directly with each, you don’t necessarily need to use keys:

post '/settings' do
params.each do |key, value|
Setting.get(key).update(:value => value)
end
end

Sinatra controller params method coming in empty on JSON post request

In order to answer this question, we're first going to have to look at some HTTP requests (which are no more than simple telnet 'messages'; this can easily be recreated by hand). First, what happens when you submit a normal HTML <form>? The POST request will look very similar to this (probably with some extra parameters, but we don't need to worry about that right now):

POST /submit-form HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 12

name=JohnDoe

Typing that character-by-character (replacing the /sample-form with whatever the URL is for any form action, and the Host with your IP or hostname) will be same thing your browser would send. The important thing to learn from this is the parameter syntax: formname=formvalue. Sinatra interprets the body of the POST request into the params hash using this syntax! Therefore, JSON requests, being substantially incompatible with this, will not show up in the params hash because of this.

However, what you're doing in your before block shows the proper solution. While params from the above would be {'name' => 'JohnDoe'}, request.body.read will return the original body, name=JohnDoe.

In knowing this, one can come to understand why your 'hacky' solution works: the original body of the POST request gets interpreted by JSON.parse, then gets inserted into the empty params hash. The reason it seems hacky is because params is a needless middleman in this example. The following should do the job:

post '/locations/new' do
@json = JSON.parse(request.body.read)
# @json now contains a hash of the submitted JSON content
end

However, a solution exercising better practice would either only respond if JSON content is provided, or respond differently if a standard form is submitted. As seen in the above example HTTP POST request, an HTML form is identified with the application/x-www-form-urlencoded MIME type, whereas JSON is identified with application/json. If you want the specifics on checking the POST request's MIME type, check out this question with some great answers on how to do this with Sinatra!

Sinatra doesn't show POST data

It's a common fault. Sinatra just parse form data (source).

To fix this use rack-contrib or the request.body.

Form parameter would look like this

curl -X POST 127.1:4567/ -d "foo=bar"

Instead of params you can just use request.body.read or use rack contrib.

rack-contrib

  1. Install it with gem install rack-contrib
  2. Require it

    require 'rack'

    require 'rack/contrib'

  3. Load it use Rack::PostBodyContentTypeParser

With this you can use params as normal for json post data. Something like this:

curl -X POST -H "Content-Type: application/json" -d '{"payload":"xyz"}' 127.1:4567/

Source for this:

  • Sinatra controller params method coming in empty on JSON post request,
  • http://jaywiggins.com/2010/03/using-rack-middleware-to-parse-json/


Related Topics



Leave a reply



Submit