I'm writing a web application in Rust using Actix-Web v1.0.7. I'm trying to create a route handler that could access a path parameter and also parse the JSON body of the request. However, so far I've failed to do so.
I tried declaring a handler function that would accept actix_web::HttpRequest
as a parameter. This gives me access to the path parameter using match_info
method without any problems. I then tried parsing the JSON body by using actix_web::web::Json::from_request
method (from actix_web::FromRequest
trait implementation), which requires 2 arguments:
&actix_web::HttpRequest
&mut actix_web::dev::Payload
My problem is getting the actix_web::dev::Payload
. I tried using the actix_web::HttpRequest::take_payload
method (from actix_web::HttpMessage
trait implementation) but the trait implementation declares a unit value as the Stream
inside the payload, which means I'm stuck. I assume this is due to the asynchronous nature of the framework, and perhaps the request body has not yet been received when the handler is invoked. However, that's just an assumption.
#[derive(Deserialize)]
struct Thing {
// ...
}
type JsonThing = Json<Thing>;
fn handle(req: HttpRequest) -> impl IntoFuture {
let id = req.match_info().query("id").parse::<usize>().unwrap();
let mut payload = req.take_payload();
JsonThing::from_request(&req, &mut payload)
.and_then(|thing| {
// ...
HttpResponse::Ok().finish()
})
}
fn main() {
let address = String::from("127.0.0.1:8080");
let scope = web::scope("/scope")
.route("/{id:\\d+}/path", web::put().to_async(handle));
HttpServer::new(|| App::new().service(scope))
.bind(address)
.unwrap()
.run()
.unwrap();
}
I know that the snippet above does not compile and contains other issues, however it conveys the general idea. I expect there is a way to get the value of ID parameter from the path and to also be able to parse the JSON body of the same request, but so far I didn't find one.