Tesla adapter for HTTPower.
This adapter allows HTTPower to work with existing Tesla clients, enabling you to add HTTPower's production features (circuit breakers, rate limiting, retry logic, PCI logging) on top of your existing Tesla setup without rewriting your HTTP infrastructure.
Features
- Works with any Tesla client configuration
- Preserves Tesla middleware stack
- Supports all Tesla adapters (Finch, Hackney, Mint, Gun, etc.)
- Transparent pass-through of Tesla features
Configuration
The Tesla adapter requires a Tesla client to be passed in the options:
# Create your Tesla client
tesla_client = Tesla.client([
Tesla.Middleware.BaseUrl.new("https://api.example.com"),
Tesla.Middleware.JSON,
Tesla.Middleware.Logger
])
# Use with HTTPower
client = HTTPower.new(
adapter: {HTTPower.Adapter.Tesla, tesla_client}
)
HTTPower.get(client, "/users")Testing
For testing, you can use Tesla's testing capabilities:
# Use Tesla.Mock for testing
Tesla.Mock.mock(fn
%{method: :get, url: "https://api.example.com/users"} ->
%Tesla.Env{status: 200, body: %{"users" => []}}
end)Or use HTTPower's test mode blocking:
Application.put_env(:httpower, :test_mode, true)
# Requests will be blocked unless using a test adapterTesla Client Middleware
The Tesla adapter respects all middleware in your Tesla client:
- Authentication middleware (Bearer, Basic, OAuth)
- Retry middleware (note: disable if using HTTPower's retry)
- Logging middleware
- Custom middleware
Important: JSON Middleware
If your Tesla client includes Tesla.Middleware.JSON, you should remove it
when wrapping with HTTPower. HTTPower handles JSON encoding/decoding via
HTTPower.Codec, and having both active will cause double-decoding:
# Before (double-decoding risk)
Tesla.client([Tesla.Middleware.JSON])
# After (correct)
Tesla.client([]) # HTTPower handles JSON via json: optionConnection options are configured on the Tesla client, not per request
Unlike the Finch and Req adapters, this adapter does not forward the
timeout, ssl_verify, or proxy request options to Tesla — Tesla
configures those on the client itself (e.g. Tesla.Middleware.Timeout and
the chosen Tesla adapter's transport/proxy options). Passing them to
HTTPower.get/2 etc. with this adapter has no effect; configure them when
you build the Tesla client instead.
Example
# Define Tesla client with middleware
defmodule MyApp.ApiClient do
use Tesla
plug Tesla.Middleware.BaseUrl, "https://api.example.com"
plug Tesla.Middleware.JSON
plug Tesla.Middleware.Headers, [{"authorization", "Bearer token"}]
# Use Finch adapter
adapter Tesla.Adapter.Finch, name: MyApp.Finch
end
# Wrap with HTTPower for production features
tesla_client = MyApp.ApiClient.client()
client = HTTPower.new(
adapter: {HTTPower.Adapter.Tesla, tesla_client},
circuit_breaker: [threshold: 5], # Future feature
rate_limit: [requests: 100, per: :second] # Future feature
)
# Make requests - Tesla handles HTTP, HTTPower adds reliability
{:ok, response} = HTTPower.get(client, "/users")