RestAPIBuilder
A simple wrapper for rest-client aiming to make creation and testing of API clients easier.
Why?
RestClient is great, but after building a few API clients with it you will almost inevitably find yourself re-implementing certain basic things such as:
- Compiling and parsing basic JSON requests/responses
- Handling and extracting details from non-200 responses
- Creating testing interfaces for your API clients
This library's tries to solve these and similar issues by providing a thin wrapper around rest-client and an optional webmock testing interface for it.
Installation
gem install rest_api_builder
WebMock interface installation
Simply require webmock interface before your test, for example in your test_helper.rb:
# test_helper.rb
require "webmock"
require "rest_api_builder/webmock_request_expectations"
WebMock.enable!
# my_spec.rb
require 'test_helper'
describe 'my test' do
it 'performs a request' do
RestAPIBuilder::WebMockRequestExpectations.expect_execute(...).to_return(body: "hi!")
result = RestAPIBuilder::Request.execute(...)
# some assertions
end
end
RestAPIBuilder::WebMockRequestExpectations expects that you have WebMock installed as a dependency.
Usage
require "rest_api_builder"
Request = RestAPIBuilder::Request
# Simple request:
response = Request.execute(base_url: "example.com", method: :get)
response[:success] #=> true
response[:status] #=> 200
response[:body] #=> "<!doctype html>\n<html>..."
response[:headers] #=> {:accept_ranges=>"bytes", ...}
# Non-200 responses:
response = Request.execute(base_url: "example.com", path: "/foo", method: :get)
response[:success] #=> false
response[:status] #=> 404
response[:body] #=> "<!doctype html>\n<html>..."
# JSON requests:
response = Request.json_execute(base_url: "api.github.com", path: "/users/octocat/orgs", method: :get)
response[:success] #=> true
response[:body] #=> []
WebMock Expectations
require "rest_api_builder"
require "webmock"
require "rest_api_builder/webmock_request_expectations"
WebMock.disable_net_connect!
Request = RestAPIBuilder::Request
Expectations = RestAPIBuilder::WebMockRequestExpectations
# Simple expectation
Expectations.expect_execute(base_url: "test.com", method: :get)
response = Request.execute(base_url: "test.com", method: :get)
response[:success] #=> true
response[:status] #=> 200
response[:body] #=> ''
response[:headers] #=> {}
# Specifying expectation details with WebMock::Request methods
Expectations
.expect_execute(base_url: "test.com", method: :get)
.to_return(status: 404, body: "not found")
response = Request.execute(base_url: "test.com", method: :get)
response[:success] #=> false
response[:status] #=> 404
response[:body] #=> "not found"
# Specifying expectation details with :request and :response options
Expectations.expect_execute(
base_url: "test.com",
method: :post,
response: { body: 'hello' },
request: { body: WebMock::API.hash_including({foo: "bar"}) }
)
response = Request.json_execute(base_url: "test.com", method: :post, body: {foo: "bar"})
response[:success] #=> true
response[:body] #=> 'hello'
Request.json_execute(base_url: "test.com", method: :post, body: {bar: "baz"}) # => Raises WebMock::NetConnectNotAllowedError
# Using #expect_json_execute
Expectations.expect_json_execute(
base_url: "test.com",
method: :get,
response: { body: {hi: 'hello'} }
)
response = Request.execute(base_url: "test.com", method: :get)
response[:success] #=> true
response[:body] #=> "{\"hi\":\"hello\"}"
Request API
RestAPIBuilder::Request.execute(options)
Performs a HTTP request via RestClient::Request.execute.\
Returns ruby hash with following keys: :success, :status, :body, :headers\
Does not throw on non-200 responses like RestClient does, but will throw on any error without defined response(e.g server timeout)
Options:
- base_url: Base URL of the request. Required.
- method: HTTP method of the request(e.g :get, :post, :patch). Required.
- path: Path to be appended to the :base_url. Optional.
- body: Request Body. Optional.
- headers: Request Headers. Optional.
- query: Query hash to be appended to the resulting url. Optional.
- logger: A
Loggerinstance to be passed to RestClient inlogoption. Will also log response details as RestClient does not do this by default. Optional - parse_json: Boolean. If
true, will attempt to parse the response body as JSON. Will return the response body unchanged if it does not contain valid JSON.falseby default. - rest_client_options: Any additional options to be passed to
RestClient::Request.executeunchanged. Any option set here will completely overwrite all custom options. For example, if you callRestAPIBuilder::Request.execute(method: :post, rest_client_options: {method: :get}), the resulting request will be sent as GET. Optional.
RestAPIBuilder::Request.json_execute(options)
A convenience shortcut for #execute which will also:
- Add
Content-Type: 'application/json'to requestheaders - Convert request
bodyto JSON - Set
parse_jsonoption totrue
WebMockRequestExpectations API
RestAPIBuilder::WebMockRequestExpectations.expect_execute(options)
Defines a request expectation using WebMock's stub_request. Returns an instance of WebMock::RequestStub on which methods such as with, to_return, to_timeout can be called
Options:
- base_url: Base URL of the request. Required.
- method: HTTP method of the request(e.g :get, :post, :patch). Required.
- path: Path to be appended to the :base_url. Optional.
- request: request details which will be passed to
WebMock::RequestStub#withif provided. Optional - response: response details which will be passed to
WebMock::RequestStub#to_returnif provided. Optional
RestAPIBuilder::WebMockRequestExpectations.expect_json_execute(options)
A convenience shortcut for #json_execute which will convert request[:body] to JSON if it's provided
License
MIT