This code works:
#[derive(Debug, Clone)]
struct SharedState {
auth: String,
token: String,
}
fn router() -> Router {
let shared_state = Arc::new(Mutex::new(SharedState {
auth: "1234".to_owned(),
token: "abcd".to_owned(),
}));
Router::new() .route("/shared_state",
get(get_shared_state)).with_state(shared_state)
}
pub async fn get_shared_state(
State(shared_state): State<Arc<Mutex<SharedState>>>,
) -> (StatusCode, Json<Value>) {
let state = shared_state.lock().unwrap();
println!("shared_state: {:?}", state);
(
StatusCode::OK,
Json(json!({
"auth": state.auth.clone(),
"token": state.token.clone()
})),
)
}
But if I change the Json<Value>
to Json<SharedState>
like below
pub async fn get_shared_state(
State(shared_state): State<Arc<Mutex<SharedState>>>,
) -> (StatusCode, Json<SharedState>) {
let state = shared_state.lock().unwrap();
println!("shared_state: {:?}", state);
(StatusCode::OK, Json(state.clone()))
}
I got the following error:
the trait bound `fn(State<Arc<Mutex<...>>>) -> ...
{get_shared_state}: Handler<_, _>` is not satisfied
Consider using `#[axum::debug_handler]` to improve the error message
the following other types implement trait `Handler<T, S>`:
`MethodRouter<S>` implements `Handler<(), S>`
`axum::handler::Layered<L, H, T, S>` implements `Handler<T, S>`
main.rs(67, 10): required by a bound introduced by this call
method_routing.rs(326, 16): required by a bound in `MethodRouter::<S>::get`
To return a Json
response, the wrapped type need to implement Serialize
from serde.
In yours and many cases, just adding the derive macro to your type is the way to go:
[dependencies]
serde = { version = "1.0.219", features = ["derive"] }
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
struct SharedState {
auth: String,
token: String,
}
After that, your handler will compile and work as you'd expect. If you need something slightly different, the derive macro is fairly customizable or of course you can implement it manually.