Hi there!
My goal is to create an Actix Web Extractor similar to built-in Form Extractor but deserializing with serde_qs crate instead.
My problem is how to read the HttpRequest body from the extractor.
In the web documentation says that the Payload Extractor is used for building other extractors, in the Doc for the Payload there is a link to an example but is not working
Sorry for my late response, originally wanted to create an extractor and pass it as a parameter in the handler function, but I read the implementation of FromRequest for String and it's about 300 lines of code. So I did it following your recommendation
Final code:
async fn route_handler(body: String, ...) -> Result<impl Responder, AppResponseError> {
let req_signin = form_parameters::<ReqSignIn>(&body, &req).await.unwrap();
...
}
/// Extract and deserialize typed data `T` from a request body. The inner type `T` must implement the
/// [`DeserializeOwned`] trait.
///
/// Returns error if:
/// - content type is not `application/x-www-form-urlencoded`
/// - fail to deseralize to `T`
pub async fn form_parameters<T: DeserializeOwned + 'static>(body: &str, req: &HttpRequest) -> Result<T, AppError> {
if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" {
return Err(AppError::BadRequest(UrlencodedError::ContentType.to_string()));
}
let qs_config = serde_qs::Config::new(2, false);
match qs_config.deserialize_str::<T>(body) {
Ok(params) => Ok(params),
Err(err) => return Err(AppError::BadRequest(err.to_string())),
}
}