Is there a way to send JSON with DELETE request with Net::HTTP?

1.9k views Asked by At

I am using Net::HTTP for CRUD request in Sinatra application. For a delete request I need to send JSON along with request:

uri = URI.parse('http://localhost:3000')    
http = Net::HTTP.new(uri.host, uri.port)
path = '/resource/resource-id'
request = Net::HTTP::Delete.new(path)
request.basic_auth('username', 'password')

response = http.request(request)

The above code sends DELETE request just fine, but when I send JSON,

request = Net::HTTP::Delete.new(path, '{"ids": ["abc123"]}')
request.basic_auth('username', 'password')

response = http.request(request)

it throws:

'400 Invalid URI'    

I have used HTTParty gem a lot and I know it serves this purpose, but I do not want to include a gem for just one API.

Any help/pointers are greatly appreciated.

Update As @kimball and @Zoker suggested, here is what I did (I am using ruby-2.0.0-p643 MRI):

request = Net::HTTP::Delete.new(path, {'Depth' => 'Infinity', 
                                       'Content-Type' =>'application/json'})
request.body = '{"ids":["abc123"]}'
request.basic_auth('username', 'password')

response = http.request(request)

it throws:

'400 Invalid URI'    

Update 2 Again as suggested in comments:

require 'json'
request.body = {"ids" => ["abc123"]}.to_json

result is still the same.

response = http.request(request)
=> #<Net::HTTPBadRequest 400 Invalid URI readbody=true>
2

There are 2 answers

4
Zoker On

the Net::HTTP::Delete.new() method provide pass params in header

# File lib/net/http.rb, line 1231
def delete(path, initheader = {'Depth' => 'Infinity'})
  request(Delete.new(path, initheader))
end
# via: http://docs.ruby-lang.org/en/2.1.0/Net/HTTP.html

you can use like this:

Net::HTTP::Delete.new(path,{'Depth' => 'Infinity', 'foo' => 'bar'})

the params in Delete.new(path,params) is a hash, not a string.

more important, the hash value must be a String

[UPDATE]

we can put a json string into request.body like this

require 'json'

request.body = JSON.generate({'foo'=>'bar','key'=>'value'})

or you can generate json string yourself

request.body = "{\"foo\":\"bar\",\"key\":\"value\"}"
0
mrtriangle On

You could also just add and if/elsif statement to your request and apply:

elsif delete
    request = Net::HTTP::Delete.new(path)
end

Where path is your specified URL