REST client wrapper around the rest-client gem: https://github.com/rest-client/rest-client
Features:
- Retries for response codes: 401 & 429; additional response codes can be added through configuration
- Authentication for: Basic, OAuth, Token; plus a Custom authenticator
- Re-authentication for: OAuth
- URI segment construction
- Pagination for: Header links and Echo
A rest_client
must be created to make requests (if the rest_client requires authentication, an authenticator can be set - see Authentication):
require "rest_client_wrapper"
# Create a rest_client
rest_client = RestClientWrapper::RestClient.new(host: "https://www.host.com")
The rest_client
can make HTTP requests using make_request
:
# Make a request
response = rest_client.make_request(http_method: :get, uri: "https://www.host.com")
The rest_client
can also make HTTP requests using execute
, which accepts a Request object. The advantage of this approach is that the URI with the segment parameters is automatically built.
Segment parameters can be added to an existing request
:
# Create an HTTP request with a segmented uri
request = Request.new(http_method: :get, uri: "/%<segment_1>s/%<segment_2>s")
# Add the segment parameter(s) to the request ('%<segment_x>s' in the uri will be replaced with the matching segment param when the request is executed)
request.segment_params = { segment_1: "user_id_0001", segment_2: "course_id_0001" }
# Execute a request
response = rest_client.execute(request: request)
Segment parameters can be created with the request
:
# Segment parameters can be created with the request
request = Request.new(http_method: :post, uri: "/%<segment_1>s", segment_params: { segment_1: "user_id_0001" }, payload: { first_name: "name" }, headers: { content_type: "application/json" })
# Execute a request
response = rest_client.execute(request: request)
The rest_client
can make authenticated HTTP requests using an authenticator
.
# Add a Basic authenticator to the rest_client
rest_client.authenticator = Authenticator::Basic.new(username: "username", password: "password")
# Make a request
response = rest_client.make_request(http_method: :get, uri: "https://www.host.com/api/v1/resource")
new
accepts the following parameters:
- type
- custom_auth_param
# Add a Custom authenticator using query_param
# The custom auth parameter will be added as a query parameter
rest_client.authenticator = Authenticator::Custom.new(type: :query_param, auth_param: { custom_auth_param: "auth_value" })
# Make a request
response = rest_client.make_request(http_method: :get, uri: "https://www.host.com/api/v1/resource")
# Add a Custom authenticator using header
# The custom auth parameter will be added to the request header
rest_client.authenticator = Authenticator::Custom.new(type: :header, auth_param: { custom_auth_param: "auth_value" })
# Make a request
response = rest_client.make_request(http_method: :get, uri: "https://www.host.com/api/v1/resource")
# Add an OAuth authenticator to the rest_client
rest_client.authenticator = Authenticator::Oauth.new(site: "https://www.host.com", token_url_path: "token_url_path", client_id: "client_id", client_secret: "secret")
# Make a request
response = rest_client.make_request(http_method: :get, uri: "/api/v1/user")
# Add a Token authenticator to the rest_client
rest_client.authenticator = Authenticator::Token.new(access_token: "access_token")
# Make a request
response = rest_client.make_request(http_method: :get, uri: "/api/v1/user")
The rest_client
can make paginated HTTP requests using a paginator
.
# Add a Header links paginator to the rest_client
rest_client.paginator = Paginator::HeaderLink.new
# Make a request for paginated data
rest_client.make_request_for_pages(http_method: :get, uri: "/api/v1/user")
# Add an Echo paginator to the rest_client
rest_client.paginator = Paginator::Echo.new
rest_client.make_request_for_pages(http_method: :get, uri: "/api/v1/user")
rest_client
has the following accessors:
- authenticator
- paginator
rest_client
has the following methods:
new
accepts the following parameters:
- host
- config (optional)
new
returns a Client object.
Client provides the following default configuration:
config = {
retries: {
401 => { max_retry: 1, wait: 0 }, # Unauthorized
429 => { max_retry: 3, wait: 3 } # Too Many Requests
}
}
rest_client = RestClientWrapper::RestClient.new(host: "host")
If the caller wishes for additional HTTP codes to be handled, they can be specified in the config
:
config = {
retries: {
431 => { max_retry: 2, wait: 1 }, # Request Header Fields Too Large
500 => { max_retry: 2, wait: 1 } # Internal Server Error
}
}
rest_client = RestClientWrapper::RestClient.new(host: "host", config: config)
make_request
accepts the following parameters:
- http_method
- uri
- payload (optional)
- query_params (optional)
- headers (optional)
make_request
returns a Response object.
make_request_for_pages
accepts the following parameters:
- http_method
- uri
- query_params (optional)
- headers (optional)
- data (optional)
make_request_for_pages
returns:
- an array where each element is a Response object for each page (ie header and the body), if data is false.
- an array where each element is one entity from every
response.body
for each page (ie the data), if data is true.
execute
accepts the following parameters:
- request
execute
returns a Response object.
authenticator
has the following methods:
generate_auth
returns a hash that is suitable for use in a Request.
new
accepts the following parameters:
- username
- password
new
returns a Basic (Authenticator) object.
new
accepts the following parameters:
- type
- auth_param
new
returns a Custom (Authenticator) object.
new
accepts the following parameters:
- site
- token_url_path
- client_id
- client_secret
new
returns an Oauth (Authenticator) object.
new
accepts the following parameters:
- access_token
new
returns a Token (Authenticator) object.
tokens
returns all of the token(s) for the authenticator
.
access_token
returns the access token for the client_id
of the authenticator
.
authenticate
accepts the following parameters:
- client_id
- access_token
authenticate
authenticates the rest_client using the client_id
and access_token
and updates the tokens
for the rest_client.
paginator
has the following accessors:
- rest_client
paginator
has the following methods:
paginate
accepts the following parameters:
- http_method
- uri
- payload (optional)
- headers (optional)
- data (optional)
paginate
returns:
- an array where each element is a Response object for each page (ie header and the body), if data is false.
- an array where each element is one entity from every
response.body
for each page (ie the data), if data is true.
new
accepts the following parameters:
- per_page (optional)
new
returns a HeaderLink (Paginator) object.
new
accepts the following parameters:
- limit (optional)
new
returns an Echo (Paginator) object.
request
has the following accessors:
- uri
- headers
- http_method
- payload
- query_params
- segment_params
request
has the following methods:
new
accepts the following parameters:
- http_method
- uri
- segment_params (optional)
- payload (optional)
- query_params (optional)
- headers (optional)
new
returns a Request object.
Response objects have the following methods:
code
: The HTTP response codebody
: The response body will be returned as a hash if the content-type of the response is a string otherwise it will return a stringheaders
: A hash of HTTP response header objects
RestClientError
: Exceptions that are raised by the rest-client GEM will be captured in this exceptionRestClientNotSuccessful
: Unsuccessful requests (i.e. aresponse
with a status that is not between 200 and 207)- Get server response by calling .response on the exception
begin
request = Request.new(http_method: :get, uri: "https://www.host.com/public/api/v1/resource")
response = rest_client.execute(request: request)
rescue RestClientError => e
e.response
end
host_url = "https://www.host.com"
username = "api_user_name"
password = "password"
client = Client.new(host: host_url)
client.authenticator = Authenticator::Basic.new(username: username, password: password)
client.paginator = Paginator::HeaderLink.new(per_page: 10)
response = client.make_request(http_method: :get, uri: "/api/v1/resource")
# paginated request
data = client.make_request_for_pages(http_method: :get, uri: "/api/v1/resource", data: true)
canvas_host = "https://host.instructure.com"
canvas_access_token = "access_token"
canvas_client = Client.new(host: canvas_host)
canvas_client.authenticator = Authenticator::Token.new(access_token: canvas_access_token)
canvas_client.paginator = Paginator::HeaderLink.new(per_page: 10)
canvas_response = canvas_client.make_request(http_method: :get, uri: "/api/v1/accounts/1/terms")
# paginated request
canvas_data = canvas_client.make_request_for_pages(http_method: :get, uri: "/api/v1/accounts/1/terms", data: true)
echo_host = "https://echo360.net.au"
echo_client_id = "client_id"
echo_client_secret = "client_secret"
echo_client = Client.new(host: echo_host)
echo_client.authenticator = Authenticator::Oauth.new(site: echo_host, token_url_path: "/oauth2/access_token", client_id: echo_client_id, client_secret: echo_client_secret)
echo_client.paginator = Paginator::Echo.new(limit: 10)
echo_response = echo_client.make_request(http_method: :get, uri: "/public/api/v1/terms")
echo_data = echo_client.make_request_for_pages(http_method: :get, uri: "/public/api/v1/terms", data: true)
Create a rest_client
.
rest_client = RestClientWrapper::RestClient.new(host: "https://www.host.com")
request = Request.new(http_method: :get, uri: "https://www.host.com/public/api/v1/users/%<user_id>s")
request.segment_params = { user_id: "user_id" }
response = rest_client.execute(request: request)
rest_client = RestClientWrapper::RestClient.new(host: "https://www.host.com")
request = Request.new(http_method: :get, uri: "/public/api/v1/users/%<user_id>s")
request.segment_params = { user_id: "user_id" }
response = rest_client.execute(request: request)
rest_client = RestClientWrapper::RestClient.new(host: "https://www.host.com")
request = Request.new(http_method: :put, uri: "/api/v1/resource/")
request.payload = { user_id: "user_id" }
request.query_params = { id: "value" }
response = rest_client.execute(request: request)