[Awesome Ruby Gem] Use http gem to make requests from Ruby

http

HTTP (The Gem! a.k.a. http.rb) is an easy-to-use client library for making requests from Ruby. It uses a simple method chaining system for building requests, similar to Python’s Requests - http://docs.python-requests.org/en/latest/.

Under the hood, http.rb uses the llhttp - https://llhttp.org/ parser, a fast HTTP parsing native extension. This library isn’t just yet another wrapper around Net::HTTP. It implements the HTTP protocol natively and outsources the parsing to native extensions.

Another Ruby HTTP library? Why should I care?

There are a lot of HTTP libraries to choose from in the Ruby ecosystem. So why would you choose this one?

Top three reasons:

  • Clean API: http.rb offers an easy-to-use API that should be a breath of fresh air after using something like Net::HTTP.

  • Maturity: http.rb is one of the most mature Ruby HTTP clients, supporting features like persistent connections and fine-grained timeouts.

  • Performance: using native parsers and a clean, lightweight implementation, http.rb achieves the best performance of any Ruby HTTP library which implements the HTTP protocol in Ruby instead of C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HTTP client	Time	Implementation
curb (persistent) 2.519 libcurl wrapper
em-http-request 2.731 EM + http_parser.rb
Typhoeus 2.851 libcurl wrapper
StreamlyFFI (persistent) 2.853 libcurl wrapper
http.rb (persistent) 2.970 Ruby + http_parser.rb
http.rb 3.588 Ruby + http_parser.rb
HTTParty 3.931 Net::HTTP wrapper
Net::HTTP 3.959 Pure Ruby
Net::HTTP (persistent) 4.043 Pure Ruby
open-uri 4.479 Net::HTTP wrapper
Excon (persistent) 4.618 Pure Ruby
Excon 4.701 Pure Ruby
RestClient 26.838 Net::HTTP wrapper

Installation

You can install it as a gem:

1
$ gem install http

or add it into a Gemfile (Bundler):

1
2
3
4
5
# Gemfile

# GitHub - httprb/http: HTTP (The Gem! a.k.a. http.rb) - a fast Ruby HTTP client with a chainable API, streaming support, and timeouts
# https://github.com/httprb/http
gem 'http', '5.0.1'

Then, run bundle install.

1
$ bundle install

Usages

Here’s some simple examples to get you started:

Making Requests

Getting started making basic requests

1
2
>> HTTP.get("https://github.com").to_s
=> "\n\n\n<!DOCTYPE html>\n<html lang=\"en\" class=\"\">\n <head prefix=\"o..."

That’s all it takes! To obtain an HTTP::Response object instead of the response body, all we have to do is omit the #to_s on the end:

1
2
>> HTTP.get("https://github.com")
=> #<HTTP::Response/1.1 200 OK {"Server"=>"GitHub.com", "Date"=>"Tue, 10 May...>

We can also obtain an HTTP::Response::Body object for this response:

1
2
>> HTTP.get("https://github.com").body
=> #<HTTP::Response::Body:3ff756862b48 @streaming=false>

Status

1
2
3
4
response.status.success? # 2XX
response.status.client_error? # 4XX
response.status.server_error? # 5XX
# etc.

The response body can be streamed with HTTP::Response::Body#readpartial. In practice, you’ll want to bind the HTTP::Response::Body to a local variable and call #readpartial on it repeatedly until it returns nil:

1
2
3
4
5
6
7
8
9
>> body = HTTP.get("https://github.com").body
=> #<HTTP::Response::Body:3ff756862b48 @streaming=false>
>> body.readpartial
=> "\n\n\n<!DOCTYPE html>\n<html lang=\"en\" class=\"\">\n <head prefix=\"o..."
>> body.readpartial
=> "\" href=\"/apple-touch-icon-72x72.png\">\n <link rel=\"apple-touch-ic..."
# ...
>> body.readpartial
=> nil

Many other HTTP methods are available as well:

1
2
3
4
5
>> response = HTTP.post('https://restapi.com/objects')
>> response = HTTP.put('https://restapi.com/put')
>> response = HTTP.patch('https://restapi.com/put')
>> response = HTTP.delete('https://restapi.com/put')
>> response = HTTP.head('https://restapi.com/put')

Passing Parameters

Query string parameters

Use the :params option to add query string parameters to requests:

1
HTTP.get("http://example.com/resource", :params => {:foo => "bar"})

Form data

Use the :form option to pass data serialized as form encoded:

1
HTTP.post("http://example.com/resource", :form => {:foo => "42"})

Request bodies

The :body option allows posting a raw request body:

1
HTTP.post("http://example.com/resource", :body => "foo=42&bar=baz")

Request bodies can be String, Enumerable or IO-like object. Enumerable and IO-like objects can be used for streaming request bodies.

The :json option allows serializing Ruby objects as JSON:

1
HTTP.post("http://example.com/resource", :json => { :foo => "42" })

File uploads (via form data)

To upload files in multipart format, construct the form as follows:

1
2
3
4
HTTP.post("http://example.com/resource", :form => {
:username => "ixti",
:avatar => HTTP::FormData::File.new("/home/ixit/avatar.png")
})

File uploads (raw)

To upload files in raw format, pass the file as the request body:

1
HTTP.post("http://example.com/resource", body: File.open("/home/ixit/avatar.png"))

See Home · httprb/http Wiki · GitHub - https://github.com/httprb/http/wiki to learn more usages.

References

[1] GitHub - httprb/http: HTTP (The Gem! a.k.a. http.rb) - a fast Ruby HTTP client with a chainable API, streaming support, and timeouts - https://github.com/httprb/http

[2] http | RubyGems.org | your community gem host - https://rubygems.org/gems/http

[3] Home · httprb/http Wiki · GitHub - https://github.com/httprb/http/wiki