Simple HTTP and REST client for Ruby, inspired by microframework syntax for specifying actions.
# REST Client -- simple DSL for accessing HTTP and REST resources
A simple HTTP and REST client for Ruby, inspired by the Sinatra's microframework style
of specifying actions: get, put, post, delete.
* Main page: https://github.com/rest-client/rest-client
* Mailing list: https://groups.io/g/rest-client
### New mailing list
We have a new email list for announcements, hosted by Groups.io.
* Subscribe on the web: https://groups.io/g/rest-client
* Subscribe by sending an email: mailto:
[email protected]
* Open discussion subgroup: https://groups.io/g/rest-client+discuss
The old Librelist mailing list is *defunct*, as Librelist appears to be broken
and not accepting new mail. The old archives are still up, but have been
imported into the new list archives as well.
http://librelist.com/browser/rest.client
## Requirements
MRI Ruby 2.0 and newer are supported. Alternative interpreters compatible with
2.0+ should work as well.
Earlier Ruby versions such as 1.8.7, 1.9.2, and 1.9.3 are no longer supported. These
versions no longer have any official support, and do not receive security
updates.
The rest-client gem depends on these other gems for usage at runtime:
* [mime-types](http://rubygems.org/gems/mime-types)
* [netrc](http://rubygems.org/gems/netrc)
* [http-accept](https://rubygems.org/gems/http-accept)
* [http-cookie](https://rubygems.org/gems/http-cookie)
There are also several development dependencies. It's recommended to use
[bundler](http://bundler.io/) to manage these dependencies for hacking on
rest-client.
### Upgrading to rest-client 2.0 from 1.x
Users are encouraged to upgrade to rest-client 2.0, which cleans up a number of
API warts and wrinkles, making rest-client generally more useful. Usage is
largely compatible, so many applications will be able to upgrade with no
changes.
Overview of significant changes:
* requires Ruby >= 2.0
* `RestClient::Response` objects are a subclass of `String` rather than a
Frankenstein monster. And `#body` or `#to_s` return a true `String` object.
* cleanup of exception classes, including new `RestClient::Exceptions::Timeout`
* improvements to handling of redirects: responses and history are properly
exposed
* major changes to cookie support: cookie jars are used for browser-like
behavior throughout
* encoding: Content-Type charset response headers are used to automatically set
the encoding of the response string
* HTTP params: handling of GET/POST params is more consistent and sophisticated
for deeply nested hash objects, and `ParamsArray` can be used to pass ordered
params
* improved proxy support with per-request proxy configuration, plus the ability
to disable proxies set by environment variables
* default request headers: rest-client sets `Accept: */*` and
`User-Agent: rest-client/...`
See [history.md](./history.md) for a more complete description of changes.
## Usage: Raw URL
Basic usage:
```ruby
require 'rest-client'
RestClient.get(url, headers={})
RestClient.post(url, payload, headers={})
```
In the high level helpers, only POST, PATCH, and PUT take a payload argument.
To pass a payload with other HTTP verbs or to pass more advanced options, use
`RestClient::Request.execute` instead.
More detailed examples:
```
…
```
## Passing advanced options
The top level helper methods like RestClient.get accept a headers hash as
their last argument and don't allow passing more complex options. But these
helpers are just thin wrappers around `RestClient::Request.execute`.
```ruby
RestClient::Request.execute(method: :get, url: 'http://example.com/resource',
timeout: 10)
RestClient::Request.execute(method: :get, url: 'http://example.com/resource',
ssl_ca_file: 'myca.pem',
ssl_ciphers: 'AESGCM:!aNULL')
```
You can also use this to pass a payload for HTTP verbs like DELETE, where the
`RestClient.delete` helper doesn't accept a payload.
```ruby
RestClient::Request.execute(method: :delete, url: 'http://example.com/resource',
payload: 'foo', headers: {myheader: 'bar'})
```
Due to unfortunate choices in the original API, the params used to populate the
query string are actually taken out of the headers hash. So if you want to pass
both the params hash and more complex options, use the special key
`:params` in the headers hash. This design may change in a future major
release.
```ruby
RestClient::Request.execute(method: :get, url: 'http://example.com/resource',
timeout: 10, headers: {params: {foo: 'bar'}})
➔ GET http://example.com/resource?foo=bar
```
## Multipart
Yeah, that's right! This does multipart sends for you!
```ruby
RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb')
```
This does two things for you:
- Auto-detects that you have a File value sends it as multipart
- Auto-detects the mime of the file and sets it in the HEAD of the payload for each entry
If you are sending params that do not contain a File object but the payload needs to be multipart then:
```ruby
RestClient.post '/data', {:foo => 'bar', :multipart => true}
```
## Usage: ActiveResource-Style
```ruby
resource = RestClient::Resource.new 'http://example.com/resource'
resource.get
private_resource = RestClient::Resource.new 'https://example.com/private/resource', 'user', 'pass'
private_resource.put File.read('pic.jpg'), :content_type => 'image/jpg'
```
See RestClient::Resource module docs for details.
## Usage: Resource Nesting
```ruby
site = RestClient::Resource.new('http://example.com')
site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
```
See `RestClient::Resource` docs for details.
## Exceptions (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
- for result codes between `200` and `207`, a `RestClient::Response` will be returned
- for result codes `301`, `302` or `307`, the redirection will be followed if the request is a `GET` or a `HEAD`
- for result code `303`, the redirection will be followed and the request transformed into a `GET`
- for other cases, a `RestClient::ExceptionWithResponse` holding the Response will be raised; a specific exception class will be thrown for known error codes
- call `.response` on the exception to get the server's response
```ruby
>> RestClient.get 'http://example.com/nonexistent'
Exception: RestClient::NotFound: 404 Not Found
>> begin
RestClient.get 'http://example.com/nonexistent'
rescue RestClient::ExceptionWithResponse => e
e.response
end
=>
```
### Other exceptions
While most exceptions have been collected under `RestClient::RequestFailed` aka
`RestClient::ExceptionWithResponse`, there are a few quirky exceptions that
have been kept for backwards compatibility.
RestClient will propagate up exceptions like socket errors without modification:
```ruby
>> RestClient.get 'http://localhost:12345'
Exception: Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 12345
```
RestClient handles a few specific error cases separately in order to give
better error messages. These will hopefully be cleaned up in a future major
release.
`RestClient::ServerBrokeConnection` is translated from `EOFError` to give a
better error message.
`RestClient::SSLCertificateNotVerified` is raised when HTTPS validation fails.
Other `OpenSSL::SSL::SSLError` errors are raised as is.
### Redirection
By default, rest-client will follow HTTP 30x redirection requests.
__New in 2.0:__ `RestClient::Response` exposes a `#history` method that returns
a list of each response received in a redirection chain.
```ruby
>> r = RestClient.get('http://httpbin.org/redirect/2')
=>
# see each response in the redirect chain
>> r.history
=> [, ]
# see each requested URL
>> r.request.url
=> "http://httpbin.org/get"
>> r.history.map {|x| x.request.url}
=> ["http://httpbin.org/redirect/2", "http://httpbin.org/relative-redirect/1"]
```
#### Manually following redirection
To disable automatic redirection, set `:max_redirects => 0`.
__New in 2.0:__ Prior versions of rest-client would raise
`RestClient::MaxRedirectsReached`, with no easy way to access the server's
response. In 2.0, rest-client raises the normal
`RestClient::ExceptionWithResponse` as it would with any other non-HTTP-20x
response.
```ruby
>> RestClient::Request.execute(method: :get, url: 'http://httpbin.org/redirect/1')
=> RestClient::Response 200 "{\n "args":..."
>> RestClient::Request.execute(method: :get, url: 'http://httpbin.org/redirect/1', max_redirects: 0)
RestClient::Found: 302 Found
```
To manually follow redirection, you can call `Response#follow_redirection`. Or
you could of course inspect the result and choose custom behavior.
```ruby
>> RestClient::Request.execute(method: :get, url: 'http://httpbin.org/redirect/1', max_redirects: 0)
RestClient::Found: 302 Found
>> begin
RestClient::Request.execute(method: :get, url: 'http://httpbin.org/redirect/1', max_redirects: 0)
rescue RestClient::ExceptionWithResponse => err
end
>> err
=> #
>> err.response
=> RestClient::Response 302 "> err.response.headers[:location]
=> "/get"
>> err.response.follow_redirection
=> RestClient::Response 200 "{\n "args":..."
```
## Result handling
The result of a `RestClient::Request` is a `RestClient::Response` object.
__New in 2.0:__ `RestClient::Response` objects are now a subclass of `String`.
Previously, they were a real String object with response functionality mixed
in, which was very confusing to work with.
Response objects have several useful methods. (See the class rdoc for more details.)
- `Response#code`: The HTTP response code
- `Response#body`: The response body as a string. (AKA .to_s)
- `Response#headers`: A hash of HTTP response headers
- `Response#raw_headers`: A hash of HTTP response headers as unprocessed arrays
- `Response#cookies`: A hash of HTTP cookies set by the server
- `Response#cookie_jar`:
New in 1.8 An HTTP::CookieJar of cookies
- `Response#request`: The RestClient::Request object used to make the request
- `Response#history`:
New in 2.0 If redirection was followed, a list of prior Response objects
```ruby
RestClient.get('http://example.com')
➔
begin
RestClient.get('http://example.com/notfound')
rescue RestClient::ExceptionWithResponse => err
err.response
end
➔
```
### Response callbacks, error handling
A block can be passed to the RestClient method. This block will then be called with the Response.
Response.return! can be called to invoke the default response's behavior.
```ruby
# Don't raise exceptions but return the response
>> RestClient.get('http://example.com/nonexistent') {|response, request, result| response }
=>
```
```ruby
# Manage a specific error code
RestClient.get('http://example.com/resource') { |response, request, result, &block|
case response.code
when 200
p "It worked !"
response
when 423
raise SomeCustomExceptionIfYouWant
else
response.return!(&block)
end
}
```
But note that it may be more straightforward to use exceptions to handle
different HTTP error response cases:
```ruby
begin
resp = RestClient.get('http://example.com/resource')
rescue RestClient::Unauthorized, RestClient::Forbidden => err
puts 'Access denied'
return err.response
rescue RestClient::ImATeapot => err
puts 'The server is a teapot! # RFC 2324'
return err.response
else
puts 'It worked!'
return resp
end
```
For GET and HEAD requests, rest-client automatically follows redirection. For
other HTTP verbs, call `.follow_redirection` on the response object (works both
in block form and in