NoSQL and friends

RecipeCratesCategories
Connect to MongoDBmongodbcat-asynchronous cat-database cat-web-programming
Connect to Redisrediscat-database

Connect to MongoDB

mongodb mongodb-crates.io mongodb-github mongodb-lib.rs cat-asynchronous cat-database cat-web-programming

This is the officially supported MongoDB Rust driver, a client side library that can be used to interact with MongoDB deployments in Rust applications. It uses the bson crate for BSON support. The driver contains a fully async API that requires tokio. The driver also has a sync API that may be enabled via feature flags.

use std::env;

use dotenvy::dotenv;
use mongodb::Client;
use mongodb::bson::doc;
use serde::Deserialize;
use serde::Serialize;

#[derive(Debug, Serialize, Deserialize)]
struct User {
    name: String,
    age: i32,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Read the .env file, if present
    dotenv().ok();

    // Example: mongodb://root:passwd@server:27017/
    let mongo_uri = env::var("MONGO_URI")?;
    let client = Client::with_uri_str(&mongo_uri).await?;
    let db = client.database("test_db");
    let collection = db.collection::<User>("users");

    let user = User {
        name: String::from("Alice"),
        age: 30,
    };
    collection.insert_one(user).await?;

    let filter = doc! { "name": "Alice" };
    if let Some(user) = collection.find_one(filter).await? {
        println!("Found user: {:?}", user);
    } else {
        println!("User not found");
    }

    Ok(())
}

Connect to Redis

redis redis-crates.io redis-github redis-lib.rs

Redis-rs is a high level redis library for Rust. It provides convenient access to all Redis functionality through a very flexible but low-level API. It uses a customizable type conversion trait so that any operation can return results in just the type you are expecting. This makes for a very pleasant development experience.

use std::env;

use anyhow::Context;
use anyhow::Result;
use redis::Commands;
use redis::Connection;

fn connect() -> Result<Connection> {
    let redis_host_name = env::var("REDIS_HOSTNAME")
        .context("missing environment variable REDIS_HOSTNAME")?;
    let redis_password = env::var("REDIS_PASSWORD").unwrap_or_default();
    // Does Redis server need a secure connection?
    let uri_scheme = match env::var("IS_TLS") {
        Ok(_) => "rediss",
        Err(_) => "redis",
    };
    // The URL format is
    // protocol=<protocol>]] For example, "redis://127.0.0.1/"
    let redis_conn_url =
        format!("{}://:{}@{}", uri_scheme, redis_password, redis_host_name);
    // `open` does not actually open a connection yet, but it does perform some
    // basic checks on the URL that might make the operation fail.
    Ok(redis::Client::open(redis_conn_url)?.get_connection()?)
}

fn fetch_an_integer() -> Result<isize> {
    let mut con = connect()?;
    // Throw away the result, just make sure it does not fail
    let _: () = con.set("my_key", 42)?;
    // Read back the key and return it. Because the return value
    // from the function is a result for integer, this will automatically
    // convert into one.
    Ok(con.get("my_key")?)
}

fn main() -> Result<()> {
    let my_int = fetch_an_integer()?;
    println!("{}", my_int);
    Ok(())
}