How to use mongodb with actix-web?

So I created a small project with actix-web and mongodb in Rust. I want to call the database connection once in the main.rs and passed the 'db' variable into each routing function such as: handle_items_insert and handle_get_item.

I want thedb variable declared in fn main() to be accessible by those handler functions.
I searched the actix documentation to find something like map(), middleware, or any variation of fn to() with no success. Does anyone know how to do this ? or any suggestion how to use database with actix-web ?

Thank you.

Here's my main.rs

use actix_web::{web, App, HttpResponse, HttpServer};
use mongodb::{options::ClientOptions, Client, Collection};

mod routes;

// this router_config function can be a module in separate file
fn router_config(cfg: &mut web::ServiceConfig) -> &mut web::ServiceConfig {
    cfg.service(
        web::resource("/items/insert")
            .route(web::post().to(handle_items_insert))
            .route(web::head().to(|| HttpResponse::MethodNotAllowed())),
    )
    .service(
        web::resource("/items/get")
            .route(web::get().to(handle_get_item))
            .route(web::head().to(|| HttpResponse::MethodNotAllowed())),
    )
}


fn config(cfg: &mut web::ServiceConfig) {
    cfg.service(web::scope("/api").configure(router_config))
        .route("/", web::get().to(|| HttpResponse::Ok().body("/")));
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let bind_addr = "127.0.0.1:8080";
    println!("Server Running at {} ....", bind_addr);

    // A Client is needed to connect to MongoDB:
    let client_uri = "mongodb://127.0.0.1:27017";
    // let mut options = ClientOptions::parse(&client_uri).await?;
    // let client = Client::with_options(options)?;

    // How to make this db variable available to handler functions ?
    // let db = client.database("my_database");

    HttpServer::new(|| App::new().configure(config))
        .bind(bind_addr)?
        .run()
        .await
}
1 Like

In actix-web you share resources with route handlers using the application state: Application.

In your case, you can share the client and db like this:

struct AppState {
   pub db: Database,
   pub client: Client
}    

#[actix_web::main]
async fn main() -> std::io::Result<()> {
  let bind_addr = "127.0.0.1:8080";
  println!("Server Running at {} ....", bind_addr);

  // A Client is needed to connect to MongoDB:
  let client_uri = "mongodb://127.0.0.1:27017";
  let mut options = ClientOptions::parse(&client_uri).await?;
  let client = Client::with_options(options)?;
  let db = client.database("my_database");

HttpServer::new(|| App::new()
    .data(AppState {
            db,
            client
        })
    .configure(config))
    .bind(bind_addr)?
    .run()
    .await
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.