HTTP::API::Client
A small, dependency-light foundation for building JSON HTTP API clients in Perl.
The goal is not to replace HTTP::Tiny, LWP, or Mojo::UserAgent. It adds the API-client layer applications repeatedly rebuild: base URLs, JSON request/response handling, default headers, timeout configuration, structured errors, and conservative retries.
Example
use HTTP::API::Client;
my $api = HTTP::API::Client->new(
base_url => 'https://api.example.com',
headers => {
Authorization => "Bearer $ENV{API_TOKEN}",
},
timeout => 10,
retry => {
attempts => 3,
base_delay => 0.25,
max_delay => 5,
jitter => 1,
},
);
my $response = $api->get('/users');
my $data = $response->json;
Retry policy
Retries are intentionally conservative. By default only GET, HEAD, PUT, DELETE, and OPTIONS are retried. POST and PATCH are not automatically repeated because doing so can duplicate side effects.
Retryable failures include transport errors, HTTP 408, 425, 429, 5xx, and exhausted-quota 403 responses. Delays use exponential backoff with jitter. A numeric Retry-After header takes precedence; exhausted rate-limit reset metadata is used as a fallback.
my $api = HTTP::API::Client->new(
base_url => 'https://api.example.com',
retry => {
attempts => 4,
base_delay => 0.5,
max_delay => 10,
},
);
# Disable retry for one request.
$api->get('/status', retry => 0);
# Explicitly opt POST into retry when the endpoint is known to be idempotent.
$api->post('/jobs',
json => { task => 'sync' },
retry => {
attempts => 2,
methods => ['POST'],
},
);
Features
- base URL handling
- default and per-request headers
- JSON request encoding
- JSON response decoding
- configurable timeout
- structured transport/HTTP/encode/decode errors
- request ID extraction
- automatic retry with exponential backoff + jitter
- normalized rate-limit metadata and reset-aware retry fallback
- injectable transport for tests and custom integration
Planned
Pagination, richer rate-limit policy, and middleware/hooks.
License
Same terms as Perl itself.