fetch-kit 0.1.4

Resilient HTTP client for Rust — retry, circuit breaker, connection pooling, and typed JSON helpers built on reqwest
Documentation

fetch-kit

Rust License

Resilient HTTP client for Rust — retry, circuit breaker, connection pooling, and typed JSON helpers built on reqwest.

Naming: previously fetchkit; renamed to fetch-kit (estate convention) because fetchkit on crates.io belongs to an unrelated project (maintained by everruns). Published as fetch-kit.

Features

  • Automatic retries with exponential backoff via reqwest-retry
  • Typed JSON helpers — get_json / post_json deserialize responses directly
  • Fallback fetching — try a primary URL, fall back to another on failure
  • Circuit breaker (opt-in) — stop hammering a dead service
  • Connection pooling — inherits reqwest's connection pool
  • Pluggable middleware — built on reqwest-middleware

Quick Start

use fetch_kit::Client;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::builder()
        .base_url("https://api.example.com")
        .timeout(Duration::from_secs(10))
        .retries(5)
        .build();

    let user: serde_json::Value = client.get_json("/users/1").await?;
    println!("{user:#}");

    Ok(())
}

Circuit Breaker

Enable the circuit-breaker feature to wrap requests in a breaker that automatically rejects calls after repeated failures.

use fetch_kit::Client;
use breaker::{CircuitBreaker, CircuitBreakerConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let breaker = CircuitBreaker::new(CircuitBreakerConfig::standard());

    let client = Client::builder()
        .base_url("https://api.example.com")
        .with_breaker(breaker)
        .build();

    // When the circuit opens, requests will return Err(FetchError::CircuitOpen).
    Ok(())
}

Request Builder

use fetch_kit::Client;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::builder()
        .base_url("https://api.example.com")
        .default_header("Authorization", "Bearer token")
        .build();

    // Fluent request builder
    let value: serde_json::Value = client
        .get("/users/1")
        .timeout(Duration::from_secs(5))
        .send()
        .await?
        .json()
        .await?;

    // Or deserialize directly
    let user: serde_json::Value = client
        .post("/users")
        .json(&serde_json::json!({"name": "Alice"}))
        .json_response()
        .await?;

    Ok(())
}

Comparison with raw reqwest

raw reqwest fetch-kit
Retries manual or separate middleware built-in (configurable)
JSON helpers resp.json::<T>() each time get_json / post_json
Fallback write it yourself fetch_with_fallback
Timeout per-client or per-request builder default (30s)

License

Licensed under either of MIT or Apache-2.0 at your option.