Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive a JSON object with Rack

I have a very simple Ruby Rack server, like:

app = Proc.new do |env| 
  req = Rack::Request.new(env).params
  p req.inspect 
  [200, { 'Content-Type' => 'text/plain' }, ['Some body']]
end 

Rack::Handler::Thin.run(app, :Port => 4001, :threaded => true)

Whenever I send a POST HTTP request to the server with an JSON object:

{ "session": {
"accountId": String,
"callId": String,
"from": Object,
"headers": Object,
"id": String,
"initialText": String,
"parameters": Object,
"timestamp": String,
"to": Object,
"userType": String } } 

I receive nothing. I can detect the request received but can't get the data. The results at my console for puts req.inspect is something like:

"{}"

How am I supposed to get the data?

I tried to change that with something like:

request  = Rack::Request.new env
object   = JSON.parse request.body
puts JSON.pretty_generate(object)

But I'm getting the following warning:

!! Unexpected error while processing request: can't convert StringIO into String
like image 371
Eqbal Avatar asked Mar 14 '12 17:03

Eqbal


People also ask

How do I send and receive JSON data from server?

Use JSON. stringify() to convert the JavaScript object into a JSON string. Send the URL-encoded JSON string to the server as part of the HTTP Request. This can be done using the HEAD, GET, or POST method by assigning the JSON string to a variable.

How do I get JSON post data?

To receive JSON string we can use the “php://input” along with the function file_get_contents() which helps us receive JSON data as a file and read it into a string. Later, we can use the json_decode() function to decode the JSON string.

How do I display a JSON object?

Declare a JSON object and store it into variable. Use JSON. stringify(obj) method to convert JavaScript objects into strings and display it. Use JSON.

Can we send JSON in GET request?

To answer your question, yes you may pass JSON in the URI as part of a GET request (provided you URL-encode).


2 Answers

env['rack.input'].gets

This worked for me. I found that using curl or wget to test POST requests against a Rack (v1.4.1) server required using this code as a fallback to get the request body. POST requests out in the wild (e.g. GitHub WebHooks) didn't have this same problem.

like image 146
eddroid Avatar answered Sep 21 '22 15:09

eddroid


It seems that I'm supposed to use something like:

msg = JSON.parse env['rack.input'].read 

Then just use params in the msg hash.

At least it worked for me this way.

like image 38
Eqbal Avatar answered Sep 21 '22 15:09

Eqbal