Search code examples
rustrust-axum

How to use both a database and path-parsing in one request handler, in Axum 0.5?


I currently have working code:

    // build our application with a route
    let app = Router::new()
        .route("/api/:start/:tokens/:left/:top/:right/:bottom", get(stats))
        .route("/dbtest", get(dbtest))
        .layer(Extension(pool))
        ;
...
// we can extract the connection pool with `Extension`
async fn dbtest(
    Extension(pool): Extension<PgPool>,
) -> Result<String, (StatusCode, String)> {
    sqlx::query_scalar("select 'hello world from pg'")
        .fetch_one(&pool)
        .await
        .map_err(internal_error)
}
...
async fn stats(
    Path((start, tokens, left, top, bottom, right)): Path<(DateTime<Utc>, DashVec, u32, u32, u32, u32)>,
) -> String {
    format!("{} {:?} {:?} {:?}", start.to_rfc3339(), tokens, (left, top), (right, bottom))
}

How do I make a handler which can use both the database pool and parse its Path?


Solution

  • You define them as separate arguments:

    async fn combined(
        Extension(pool): Extension<PgPool>,
        Path((start, tokens, left, top, bottom, right)): Path<(DateTime<Utc>, DashVec, u32, u32, u32, u32)>,
    ) -> Result<String, (StatusCode, String)> {
        println!("{} {:?} {:?} {:?}", start.to_rfc3339(), tokens, (left, top), (right, bottom));
        sqlx::query_scalar("select 'hello world from pg'")
            .fetch_one(&pool)
            .await
            .map_err(internal_error)
    }
    

    Path and Extension are extractors and a handler function may have "zero or more extractors as arguments".