Can anyone please help me to understand, how can I get request details & Json body from handler?
Thanks
E.g.
async fn set_value(
State(app_state): State<Arc<Mutex<AppState>>>,
Json(b): Json<AppState>,
req: Request<Body>,
) -> impl IntoResponse {
// This is an example, there will be multiple condition based on request method or user-agent
if req.method() == Method::GET {
println!("Get Request");
} else {
println!("Post Request");
}
let mut app_state: MutexGuard<AppState> = app_state
.lock()
.map_err(|_| error!("Fail to lock mutex"))
.unwrap();
*app_state = b;
let r: String = serde_json::to_string(&b)
.map_err(|_| error!("Fail to serialize"))
.unwrap();
Response::builder()
.status(StatusCode::OK)
.header(header::CONTENT_TYPE, "application/json")
.body(r)
.map_err(|_| error!("Fail to build response"))
.unwrap()
}
Error
rror[E0277]: the trait bound `fn(axum::extract::State<Arc<std::sync::Mutex<AppState>>>, Json<AppState>, Request<Body>) -> impl Future<Output = impl IntoResponse> {set_value}: Handler<_, _, _>` is not satisfied
--> src/main.rs:187:50
|
187 | let router = router.route("/set-value", post(set_value));
| ---- ^^^^^^^^^ the trait `Handler<_, _, _>` is not implemented for fn item `fn(axum::extract::State<Arc<std::sync::Mutex<AppState>>>, Json<AppState>, Request<Body>) -> impl Future<Output = impl IntoResponse> {set_value}`
| |
| required by a bound introduced by this call
H2CO3
April 19, 2023, 5:35pm
2
What's wrong with this example? I don't get what you are trying to do and what happens instead.
Issue is I am getting this error
rror[E0277]: the trait bound `fn(axum::extract::State<Arc<std::sync::Mutex<AppState>>>, Json<AppState>, Request<Body>) -> impl Future<Output = impl IntoResponse> {set_value}: Handler<_, _, _>` is not satisfied
--> src/main.rs:187:50
|
187 | let router = router.route("/set-value", post(set_value));
| ---- ^^^^^^^^^ the trait `Handler<_, _, _>` is not implemented for fn item `fn(axum::extract::State<Arc<std::sync::Mutex<AppState>>>, Json<AppState>, Request<Body>) -> impl Future<Output = impl IntoResponse> {set_value}`
| |
| required by a bound introduced by this call
I think you're hitting the recent changes to Axum that promote a run time error to a compile time error
See "Type safe extractor ordering" in this blog post
If you want to extract the whole request you can't use other extractors after that, and any body extractor conflicts with another body extractor (extracting the whole request also extracts the body)
H2CO3
April 19, 2023, 5:52pm
5
When you hit a trait bound error, you should check the implementations . In this case, the 3-argument function applies:
impl<F, Fut, S, B, Res, M, T1, T2, T3> Handler<(M, T1, T2, T3), S, B> for F
where
F: FnOnce(T1, T2, T3) -> Fut + Clone + Send + 'static,
Fut: Future<Output = Res> + Send,
B: Send + 'static,
S: Send + Sync + 'static,
Res: IntoResponse,
T1: FromRequestParts<S> + Send,
T2: FromRequestParts<S> + Send,
T3: FromRequest<S, B, M> + Send,
From there, you can check which types implement the traits FromRequestParts
and FromRequest
.
Thanks
But now, how I am suppose to get both?
Even extensions are not accessible if I extract Request.
You can access the extensions directly on the Request
. Generally it's simpler to just create your own extractor though since that's more compatible with other extractors (assuming you implement FromRequestParts
and not FromRequest
)
system
Closed
July 18, 2023, 6:20pm
8
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.