how to add routes with state and json in axum?

  Kiến thức lập trình

Well, I have a handler like this one below. And I got issues with adding it to the axum::Router.

mismatched types
expected struct `MethodRouter<_>`
  found fn item `fn(axum::Json<PayloadIn>, axum::extract::State<Arc<AppState>>) -> impl std::future::Future<Output = axum::Json<PayloadOut>> 
#[derive(Debug, Deserialize, Clone)]
pub struct PayloadIn {
    pub smth: String
}

#[derive(Debug, Serialize)]
pub struct PayloadOut {
    pub smth: String,
    pub status: EventStatus,
}

pub async fn my_handler(
    State(state): State<SharedState>,
    Json(payload): Json<PayloadIn>, 
) -> Json<PayloadOut> {

    let event = Event{
        id: 1,
        user_id: 1,
        smth: smth.clone(),

    };
    // store in db
    let confirm = state.db.save_event(event.clone()).await;
    ...
    // publish in broker
    let confirm = state.broker.publish(event).await;
    ... 
    Json(PayloadOut{smth, EventStatus::Registered})
}

there is my router:

let db = db::get_db();
let broker = broker::get_broker();
let shared_state = Arc::new(AppState{db, broker})

let router = Router::new()
    .route("/healthcheck", get(healthcheck))
    .route("/smth", post(my_handler))
    .with_state(shared_state)
    .layer(...)
...

It works using closure captures:

use axum::extract::State;

....
let router = Router::new()
    .route("/healthcheck", get(healthcheck)
    .router("/smth", post({
        let shared_state = Arc::clone(&shared_state);
        move |json| my_handler(State(shared_state), json)
    }))
    ... 

But I don’t want to pass shared_state in every handler. And most of them need shared state. How to implement it using .with_state? Or perhaps should I switch from State to Extension ?

I found information about order of extractors in official docs. And Json(payload) consuming body is should be lower than a state extractor. I’ve already changed their order and the issue is still here. So I don’t understand what’s the problem.

LEAVE A COMMENT