Ruby: Put Request with JSON Body

Ruby: PUT Request with JSON body?

Using restclient (gem install rest-client) like this:

require 'rubygems'
require 'rest_client'
require 'json'

jdata = JSON.generate(["test"])
RestClient.put 'http://localhost:4567/users/123', jdata, {:content_type => :json}

against the following sinatra service:

require 'sinatra'
require 'json'

put '/users/:id' do |n|
data = JSON.parse(request.body.read)
"Got #{data} for user #{n}"
end

works on my computer.

Ruby POST request with JSON body

SOLVED IT!

response = Unirest.post uri, headers:{"content-length" => "500", "content-type" => "application/json", "authorization" => "Bearer" + " " + apikey}, parameters: {"Inputs" => {"input1" => {"ColumnNames" => ["Case Number", "Case Type", "Address", "Description", "Case Group", "Date Case Created", "Last Inspection Date", "Last Inspection Result", "Status", "Permit and Complaint Status URL", "Latitude", "Longitude", "Location"], "Values" => [["0", "value","value","value","value","", "","value","value","value","0", "0", "value"],["0", "value","value","value","value","", "","value","value","value","0", "0", "value"]]}}, "GlobalParameters" => {}}.to_json

TL;DR

Had to nest an array within an array nested within a couple hashes.

Using Ruby's Net/HTTP module, can I ever send raw JSON data?

After reading tadman's answer above, I looked more closely at adding data directly to the body of the HTTP request. In the end, I did exactly that:

require 'uri'
require 'json'
require 'net/http'

jsonbody = '{
"id":50071,"name":"qatest123456","pricings":[
{"id":"dsb","name":"DSB","entity_type":"Other","price":6},
{"id":"tokens","name":"Tokens","entity_type":"All","price":500}
]
}'

# Prepare request
url = server + "/v1/entities"
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.set_debug_output( $stdout )

request = Net::HTTP::Put.new(uri )
request.body = jsonbody
request.set_content_type("application/json")

# Send request
response = http.request(request)

If you ever want to debug the HTTP request being sent out, use this code, verbatim: http.set_debug_output( $stdout ). This is probably the easiest way to debug HTTP requests being sent through Ruby and it's very clear what is going on :)

Ruby: HTTP Put method

A few things:

  • You're not sending JSON in the Ruby example, it's a string representation of a Ruby hash which isn't the same. You need the JSON module or similar.
  • In the Ruby code you're attempting to send a JSON object (which would look like {"ip":"1.1.1.1"} and in the curl example you're sending it in application/x-www-form-urlencoded format, so they're currently not equivalent.
  • Also I'd look at the type of data the server expects from your requests: both Ruby and curl send a request header of Content-Type: application/x-www-form-urlencoded by default, and you're expecting to send JSON. This is why the curl example works: the data format you're using and the header matches. Note the .json in the URL shouldn't really make any difference; the header takes precedence.
  • Your call to send_request has you picking out the data parameter as a Python-style keyword argument. Ruby doesn't do that: what you're actually doing there is assigning a local variable in-line with the call.

So try something like this:

require 'json' # put this at the top of the file

uri = URI.parse("http://#{ip}:#{port}/api/v1/address_data/1.json")
jobj = {"ip" => "1.1.1.1"}
http = Net::HTTP.new(uri.hostname, uri.port)
response = http.send_request('PUT', uri.path, JSON.dump(jobj),
{'Content-Type' => 'application/json'})

And just a friendly reminder, saying something "doesn't work" doesn't usually give enough information to people that might answer your question: try and remember to paste in error messages, stack traces, and things like that :)

Posting Ruby data in JSON format with Net/http

Make a request object like so:

request = Net::HTTP::Post.new(uri.request_uri, 
'Content-Type' => 'application/json')
request.body = newAcctJson
resp = http.request(request)


Related Topics



Leave a reply



Submit