31

Is it possible to make a POST request from Ruby with open-uri?

Alexey Lebedev
  • 11,988
  • 4
  • 39
  • 47

4 Answers4

35

Unfortunately open-uri only supports the GET verb.

You can either drop down a level and use net/http, or use rest-open-uri, which was designed to support POST and other verbs. You can do gem install rest-open-uri to install it.

Martin Kenny
  • 2,468
  • 1
  • 19
  • 16
16
require 'open-uri'
require 'net/http'
params = {'param1' => 'value1', 'param2' => 'value2'}
url = URI.parse('http://thewebsite.com/thepath')
resp, data = Net::HTTP.post_form(url, params)
puts resp.inspect
puts data.inspect

It worked for me :)

Michael
  • 548
  • 8
  • 30
Venkat D.
  • 2,979
  • 35
  • 42
  • 8
    -1 This isn't using OpenURI to handle the connection, it's using Net::HTTP. In this example, OpenURI is only being used to load the URI module. – the Tin Man Jan 04 '13 at 18:27
  • Also you've declared `params` then referenced `query` – KomodoDave Jun 17 '14 at 09:40
  • doesn't matter if its using or not. if open-uri cannot do it, this answer will help a lot of people. no way to downvote this answer – mask8 Mar 16 '17 at 22:57
  • What is `data`? There is nothing in the docs which indicates what that is. https://ruby-doc.org/stdlib-2.7.4/libdoc/net/http/rdoc/Net/HTTP.html#method-c-post_form – Chloe Sep 29 '21 at 20:36
10

I'd also really recommend rest-client. It's a great base for writing an API client.

Yarin
  • 173,523
  • 149
  • 402
  • 512
tomtaylor
  • 2,309
  • 1
  • 22
  • 36
  • Kinda confused visiting the main site posted above - is this a gem I have to compile myself and include? – JohnZaj May 12 '19 at 15:19
  • I'm not sure, used it a lot. Simple for simple use case. But I was left with the impressions that its API is a little bit inconsistent and to achieve more complicated stuff, one has to go into implementation details. Like stream copying for example. – akostadinov Jan 29 '23 at 13:33
1

As simple as it gets:

require 'open-uri'
require 'net/http'

response = Net::HTTP.post_form(URI.parse("https://httpbin.org/post"), { a: 1 })

puts response.code
puts response.message
puts response.body

I recommend using response.methods - Object.methods to see all the available methods, e.g. message, header,

Bonus: POST / DELETE requests:

puts Net::HTTP.new("httpbin.org").post("/post", "a=1").body
puts Net::HTTP.new("httpbin.org").delete("/delete").body
Dorian
  • 22,759
  • 8
  • 120
  • 116