ultra-batch

Crates.ioultra-batch
lib.rsultra-batch
version0.3.0
sourcesrc
created_at2020-08-17 05:04:06.495148
updated_at2024-04-28 11:27:16.543407
descriptionTokio-based library to batch and cache database queries or other data lookups
homepage
repositoryhttps://github.com/kylewlacy/ultra-batch
max_upload_size
id277423
size111,351
Kyle Lacy (kylewlacy)

documentation

README

ultra-batch

Crate Docs Tests

ultra-batch is a Rust library to batch and cache database queries or other potentially expensive data lookups. The main motivation for this library is to solve the "N + 1" query problem seen in GraphQL and elsewhere. This library takes heavy influence from the GraphQL Foundation's DataLoader. It's designed primarily for dealing with database queries, but it can be used to batch any potentially expensive data loading operations.

Example Use

First, add tokio, async-trait, and anyhow (optional) as dependencies.

use async_trait::async_trait;
use ultra_batch::{Fetcher, Batcher, Cache};

#[derive(Debug, Clone)]
struct User {
    id: u64,
    // User model from your DB, etc.
}

struct UserFetcher {
    // Database connection, etc.
}

#[async_trait]
impl Fetcher for UserFetcher {
    // The thing we can use to look up a single `User` (like an ID)
    type Key = u64;

    // The thing we are trying to look up
    type Value = User;

    // Used to indicate the batch request failed (DB connection failed, etc)
    type Error = anyhow::Error;

    // Fetch a batch of users
    async fn fetch(
        &self,
        keys: &[Self::Key],
        values: &mut Cache<'_, Self::Key, Self::Value>,
    ) -> Result<(), Self::Error> {
        let users: Vec<User> = todo!(); // Fetch users based on the given keys
        for user in users {
            values.insert(user.id, user); // Insert all users we found
        }

        Ok(())
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let fetcher = UserFetcher { /* ... */ };
    let batcher = Batcher::build(fetcher).finish();

    // Retrieve a user by ID. If `load` gets called in other tasks/threads
    // at the same time, then all the requested IDs will get batched together
    let user = batcher.load(123).await?;

    println!("User: {:?}", user);

    Ok(())
}

Minimum Supported Rust Version (MSRV)

ultra-batch currently supports Rust v1.56. Changes to the MSRV are tracked in the Changelog.

Alternative projects

License

Licensed under either the MIT license or Apache 2.0 license (licensee's choice).

Commit count: 65

cargo fmt