A minimal, opinionated HTTP client wrapper for Rails, built on top of Typhoeus. Perfect for quickly building clean, opinionated API clients with almost no boilerplate.
- Simple class-level DSL for configuration
- Built-in support for Bearer, API Key and Basic Auth
- Chainable-like request methods (GET, POST, PATCH, PUT, DELETE, HEAD, OPTIONS)
- Small, focused API clients
- Internal services and microservices
- Rails apps that want minimal abstraction
- Developers who prefer convention over configuration
- Installation
- Basic Usage
- Rails Generator
- Configuration
- Authorization
- Making Requests
- Response Handling
- Contributing
- License
Add this line to your Gemfile:
gem "tiny-rest-client"Or install it manually:
gem install tiny-rest-clientclass MyClient < TinyRestClient::Core
# define base API path (required)
api_path "https://api.example.com/v1"
# set an authorization strategy (optional)
authorization :bearer, token: "your_token"
# pass single header (optional)
header "Accept", "application/json"
# pass bunch of headers (optional)
headers "User-Agent": "MyTest/1.0", "Accept": "application/json"
# define actions (optional)
def fetch_todos(**)
get("/todos", **)
end
def fetch_todo(id)
get("/todos/#{id}")
end
def create_todo(**)
post("/todos", **)
end
def update_todo(id, **)
patch("/todos/#{id}", **)
end
def destroy_todo(id)
delete("/todos/#{id}")
end
end
client = MyClient.new
client.fetch_todos(page: 1, per_page: 20)
client.fetch_todo(1)
client.create_todo(name: "Custom")
client.update_todo(1, { status: "finished" })
client.destroy_todo(1)The gem includes a built-in Rails generator to quickly scaffold new API clients.
rails generate tiny_rest_client:client NAME [URL] [options]| Option | Default | Description | Example Usage |
|---|---|---|---|
| NAME | (required) | Client name (supports nesting like api/v1/stripe) |
rails g ... api/v1/stripe |
| URL | (none) | Base API URL | rails g ... stripe https://api.stripe.com |
| --namespace | clients |
Root folder under app/ (e.g. app/services/) |
--namespace=services |
# Basic client
rails generate tiny_rest_client:client stripe
# Custom base URL
rails generate tiny_rest_client:client stripe https://api.stripe.com/v1
# Nested namespace (creates app/clients/api/v1/payment_client.rb)
rails generate tiny_rest_client:client api/v1/payment https://api.example.com/v1
# Custom namespace (creates app/custom/stripe_client.rb)
rails generate tiny_rest_client:client stripe https://api.example.com/v1 --namespace=customYou can configure client setup at the class level:
class MyClient < TinyRestClient::Core
api_path "https://api.example.com/v1"
authorization :bearer, token: "your_token"
headers "Accept": "application/json", "User-Agent": "MyApp/1.0"
end
client = MyClient.newOr per instance:
class MyClient < TinyRestClient::Core; end
client = MyClient.new(
api_path: "https://api.example.com/v1",
auth: { bearer: { token: "your_token" } },
headers: { "User-Agent": "MyApp/1.0" }
)The library ships with a small set of built‑in strategies:
- Bearer Token
- API Keys
- Basic Auth
You can configure authentication either at the class level using the
authorization helper or at runtime via the auth key when initializing a
client (see "Configuration" above).
# Bearer
:bearer, token: String # Authorization: Bearer <token>
# API key
:api_key, token: String # X-API-Key: <token>
:api_key, token: String, name: String # <Custom>: <token>
:api_key, token: String, in: :param # ?api_key=<token>
:api_key, token: String, in: :param, name: String # ?<custom>=<token>
# Basic
:basic_auth, user: String, password: String # Authorization: Basic <base64(user:password)>class MyClient < TinyRestClient::Core
authorization :bearer, token: "your_token"
end
# per-instance
MyClient.new(auth: { bearer: { token: "your_token" } })class MyClient < TinyRestClient::Core
authorization :api_key, token: "your_token"
end
# per-instance
MyClient.new(auth: { api_key: { token: "your_token" } })class MyClient < TinyRestClient::Core
authorization :basic_auth, user: "name", password: "secret"
end
# per-instance
MyClient.new(auth: { basic_auth: { user: "name", password: "secret" } })The standard HTTP methods are available directly on every client instance automatically include any headers or authorization configuration you defined.
get("/users", page: 1, per_page: 10) # GET request with query parameters
post("/users", name: "John", surname: "Doe") # POST request with body
put("/users/1") # PUT request
patch("/users/1") # PATCH request
delete("/users/1") # DELETE request
head("/users/1") # HEAD request
options("/users") # OPTIONS requestEvery request returns an instance of TinyRestClient::Response. A thin wrapper around the raw Typhoeus response that provides a few convenient helpers:
| Method | Description |
|---|---|
| success? | Helper that represent successful response. |
| failure? | The opposite. |
| code | HTTP status code (e.g. 200, 404). |
| status | Return code symbol (e.g. :ok, :couldnt_connect). |
| headers | Hash of response headers (keys are not normalized). |
| body | Auto-parsed JSON (symbolized keys). If parsing fails, returns the original raw string. |
response.success? # true if code 200–299
response.failure? # opposite
response.code # HTTP status code
response.status # Typhoeus return_code symbol
response.body # auto-parsed JSON hash or raw string
response.headers # hash of response headersTinyRestClient does not raise exceptions for HTTP status codes.
Network-level errors (timeouts, connection failures, etc.) are reflected in:
- response.status
- response.success? / response.failure?
This makes error handling explicit and predictable.
Bug reports and pull requests are welcome on GitHub.
The gem is available as open source under the terms of the MIT License.