rustrust-axum

Rust Axum pass state to nested routers


Here is the main Router inside async fn main()

let pool = PgPoolOptions::new()
    .max_connections(5)
    .acquire_timeout(Duration::from_secs(3))
    .connect(&db_connection_str)
    .await
    .expect("can't connect to database");

let app = Router::new().nest("/products", create_products_router()).with_state(&pool);

Getting this error under &pool

Type mismatch [E0308] expected (), but found &sqlx_core::pool::Pool<sqlx_postgres::database::Postgres>

And here is the nested Router

pub fn create_products_router() -> Router {
    Router::new()
        .route("/products", get(get_products_list::get_products_list))
}

Getting this error:

Type mismatch [E0308] expected axum::routing::method_routing::MethodRouter, but found axum::routing::method_routing::MethodRouter<sqlx_postgres::PgPool>

Finally the function itself

pub async fn get_products_list(State(pool): State<PgPool>,) -> Result<String, (StatusCode, String)> {
   sqlx::query_scalar("select * from product")
        .fetch(&pool)
       .await
       .map_err(internal_error)
}

How do I pass pool from the main Router to nested Router to get_products_list function?


Solution

  • In the type Router<S>, S is the type of the missing state. In this function:

    pub fn create_products_router() -> Router { ... }
    

    Since you have not specified S, it defaults to (). Explicitly specify the generic argument to be the type of state the router needs:

    pub fn create_products_router() -> Router<PgPool> { ... }