http-cache-tower

Crates.iohttp-cache-tower
lib.rshttp-cache-tower
version1.0.0-alpha.2
created_at2025-07-28 02:26:51.588202+00
updated_at2025-08-25 03:15:45.571906+00
descriptionHTTP cache middleware for Tower/Hyper
homepagehttps://http-cache.rs
repositoryhttps://github.com/06chaynes/http-cache
max_upload_size
id1770602
size230,355
Christian Haynes (06chaynes)

documentation

README

http-cache-tower

CI Crates.io Docs.rs Codecov Crates.io

An HTTP caching middleware for Tower and Hyper.

This crate provides Tower Layer and Service implementations that add HTTP caching capabilities to your HTTP clients and services.

Minimum Supported Rust Version (MSRV)

1.82.0

Install

With cargo add installed :

cargo add http-cache-tower

Features

The following features are available. By default manager-cacache is enabled.

  • manager-cacache (default): enable cacache, a high-performance disk cache, backend manager.
  • manager-moka (disabled): enable moka, a high-performance in-memory cache, backend manager.
  • streaming (disabled): enable streaming cache support for memory-efficient handling of large responses using StreamingManager.

Example

Basic HTTP Cache

use http_cache_tower::HttpCacheLayer;
use http_cache::CACacheManager;
use tower::{ServiceBuilder, ServiceExt};
use http::{Request, Response};
use http_body_util::Full;
use bytes::Bytes;
use std::path::PathBuf;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a cache manager
    let cache_manager = CACacheManager::new(PathBuf::from("./cache"), false);

    // Create the cache layer
    let cache_layer = HttpCacheLayer::new(cache_manager);

    // Build your service stack
    let service = ServiceBuilder::new()
        .layer(cache_layer)
        .service_fn(|_req: Request<Full<Bytes>>| async {
            Ok::<_, std::convert::Infallible>(
                Response::new(Full::new(Bytes::from("Hello, world!")))
            )
        });

    // Use the service
    let request = Request::builder()
        .uri("https://httpbin.org/cache/300")
        .body(Full::new(Bytes::new()))?;

    let response = service.oneshot(request).await?;

    println!("Status: {}", response.status());

    Ok(())
}

Streaming HTTP Cache

For large responses or when memory efficiency is important, use the streaming cache layer:

# #[cfg(feature = "streaming")]
use http_cache_tower::HttpCacheStreamingLayer;
# #[cfg(feature = "streaming")]
use http_cache::StreamingManager;
# #[cfg(feature = "streaming")]
use tower::{ServiceBuilder, ServiceExt};
# #[cfg(feature = "streaming")]
use http::{Request, Response};
# #[cfg(feature = "streaming")]
use http_body_util::Full;
# #[cfg(feature = "streaming")]
use bytes::Bytes;
use std::path::PathBuf;

# #[cfg(feature = "streaming")]
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // StreamingManager provides optimal streaming with no buffering
    let streaming_manager = StreamingManager::new(PathBuf::from("./cache"));

    // Create the streaming cache layer
    let cache_layer = HttpCacheStreamingLayer::new(streaming_manager);

    // Build your service stack
    let service = ServiceBuilder::new()
        .layer(cache_layer)
        .service_fn(|_req: Request<Full<Bytes>>| async {
            Ok::<_, std::convert::Infallible>(
                Response::new(Full::new(Bytes::from("Large response data...")))
            )
        });

    // Use the service - responses are streamed without buffering entire body
    let request = Request::builder()
        .uri("https://example.com/large-file")
        .body(Full::new(Bytes::new()))?;

    let response = service.oneshot(request).await?;

    println!("Status: {}", response.status());

    Ok(())
}

# #[cfg(not(feature = "streaming"))]
# fn main() {}

Note: For memory-efficient streaming of large responses, use StreamingManager with HttpCacheStreamingLayer. For traditional caching with smaller responses, use CACacheManager or MokaManager with HttpCacheLayer.

Cache Backends

This crate supports multiple cache backends through feature flags:

  • manager-cacache (default): Disk-based caching using cacache
  • manager-moka: In-memory caching using moka

Integration with Hyper Client

use http_cache_tower::HttpCacheLayer;
use http_cache::CACacheManager;
use hyper_util::client::legacy::Client;
use hyper_util::rt::TokioExecutor;
use tower::{ServiceBuilder, ServiceExt};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let cache_manager = CACacheManager::default();
    let cache_layer = HttpCacheLayer::new(cache_manager);

    let client = Client::builder(TokioExecutor::new()).build_http();

    let cached_client = ServiceBuilder::new()
        .layer(cache_layer)
        .service(client);

    // Now use cached_client for HTTP requests
    Ok(())
}

Documentation

License

Licensed under either of

at your option.

Commit count: 449

cargo fmt