Skip to content

api-client

HTTP client gem with concurrent execution, circuit breaker, request flow pipelines, and JWT authentication. Built on Faraday.

Why

NeedFaraday aloneapi-client
Sequential HTTP
Batch/concurrentmanual Typhoeusauto-detected
Circuit breakermanual Stoplightbuilt-in
Request pipelinesfetch → then → fan_out → collect
JWT authmanual4-phase key rotation
SSRF preventionUriPolicy with blocklist

Install

ore

ore add api-client -github belt/api-client
ore add typhoeus faraday-typhoeus async async-http concurrent-ruby jwt fiddle
ore install

Bundler

In Gemfile add:

gem"api-client",github: "belt/api-client"gem"typhoeus"# optional: HTTP/2 adaptergem"faraday-typhoeus"# optional: Faraday integration for typhoeusgem"async"# optional: fiber-based adaptergem"async-http"# optional: async HTTP transportgem"concurrent-ruby"# optional: thread pool adaptergem"jwt"# optional: JWT authenticationgem"fiddle"# optional: native RSS measurement
bundle

Quick start

See doc/onboarding.md for the full guide.

client=ApiClient.new(url: "https://api.example.com")# Simpleresponse=client.get("/users/1")# Concurrent (auto-selects Typhoeus > Async > Concurrent)responses=client.concurrent([{method: :get,path: "/users/1"},{method: :get,path: "/users/2"},])# Pipelineposts=client.request_flow.fetch(:get,"/users/123").then{ |r| JSON.parse(r.body)["post_ids"]}.fan_out{ |id| {method: :get,path: "/posts/#{id}"}}.collect

Architecture

See doc/architecture.md for full system diagrams, data flow, and component responsibilities.

ApiClient::Base
├── Connection (Faraday + middleware + pool)
├── Orchestrators
│ ├── Sequential
│ └── Batch (auto-detected backend)
├── Adapters
│ ├── Typhoeus (HTTP/2 via libcurl Hydra)
│ ├── Async (fiber-based)
│ └── Concurrent (thread pool)
├── Processing
│ ├── RactorProcessor (CPU parallelism)
│ ├── AsyncProcessor (fork isolation)
│ └── ConcurrentProcessor (thread pool)
├── RequestFlow (chained pipelines)
├── Streaming::FanOutExecutor (backpressure + retry)
├── Circuit (Stoplight integration)
├── JWT::Authenticator (Bearer injection)
└── Hooks (ActiveSupport::Notifications, 30+ events)

Configuration

ApiClient.configuredo |c|
c.service_uri="https://api.example.com"c.open_timeout=5c.read_timeout=30c.adapter=:typhoeus# or :async, :concurrentc.on_error=:raise# or :collect, :skipend

Adapters

Auto-detection priority: Typhoeus → Async → Concurrent. Per-adapter guides in doc/onboarding/.

AdapterMechanismBest for
Typhoeuslibcurl Hydra, HTTP/2High-throughput I/O
AsyncRuby fibersLightweight concurrency
ConcurrentThread poolCPU-bound post-processing

JWT

authenticator=ApiClient::JWT::Authenticator.new(jwks_uri: "https://auth.example.com/.well-known/jwks.json",audience: "api.example.com",)client=ApiClient.new(url: "https://api.example.com")do |c|
c.jwt_authenticator=authenticatorend

KeyStore supports 4-phase rotation: active → retiring → retired → revoked. See doc/auth/jwt.md for full configuration and key management.

Processing

ProcessorIsolationUse case
RactorProcess-level (Ractor::Port)CPU-bound transforms
AsyncForkUntrusted workloads
ConcurrentThread poolI/O-bound fan-out

Examples

16 canonical clients in lib/api_client/examples/ covering the 4×4 adapter × processor matrix. Each has a matching spec.

Run all: bundle exec rake examples:metrics See doc/example-metrics.md for benchmark data.

Development

bundle install
bundle exec rspec
bundle exec rake quality # rubycritic, reek, flay, flog# Install pre-push hook (CI parity gate on main)
git config core.hooksPath .githooks

Requirements

  • Ruby ≥ 3.2
  • Faraday ≥ 2.0
  • ActiveSupport ≥ 6.0

Optional

GemEnables
typhoeusHTTP/2 adapter via libcurl Hydra
faraday-typhoeusFaraday integration for typhoeus
async, async-httpFiber-based concurrent adapter
concurrent-rubyThread pool adapter
jwtJWT authentication and key rotation
fiddleNative RSS measurement via FFI

License

Apache-2.0

About

A wrapper around faraday and addons

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages