I'm trying to implement HTTP validation for Axum, just as we have in the official example, but I keep getting an error that says sync_trait proc_macro async_trait expected 1 argument, found 2. I really can't seem to figure out what I am doing wrong. Here is my implementation
/// use this to encapsulate fields that require validation
#[derive(Debug, Clone, Copy, Default)]
pub struct ValidatedRequest<T>(pub T);
#[async_trait]
impl<T, S, B> FromRequest<S, B> for ValidatedRequest<T>
where
T: DeserializeOwned + Validate,
S: Send + Sync,
Form<T>: FromRequest<S, B, Rejection = FormRejection>,
B: Send + 'static,
{
type Rejection = ApiErrorResponse;
async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
let Form(value) = Form::<T>::from_request(req, state).await?;
value.validate()?;
Ok(ValidatedRequest(value))
}
}
The example you linked is from the main branch and includes the axum dependency (here) like this: axum = { path = "../../axum" }. In other words it's using the absolute latest in-development version of axum and it's not guaranteed to work with any version of axum that's on crates.io. You'll want to look at the tags and find one that's associated with the version you're using, for example axum/main.rs at axum-v0.5.16 · tokio-rs/axum · GitHub is the example at the axum-v0.5.16 tag.
Thank you that works.
However, I think I ran into a bigger issue.
``` the official example uses accept form data. On the contrary, my API is supposed to accept JSON. Is there any modification that can be made to achieve this. I tried changing Form to Json, but it won work
let Json(value) = Json::<T>::from_request(req).await?;
Here is the full code
/// use this to encapsulate fields that require validation
#[derive(Debug, Clone, Copy, Default)]
pub struct ValidatedRequest<T>(pub T);
#[async_trait]
impl<T, B> FromRequest<B> for ValidatedRequest<T>
where
T: DeserializeOwned + Validate,
B: http_body::Body + Send,
B::Data: Send,
B::Error: Into<BoxError>,
{
type Rejection = ServerError;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
let Form(value) = Form::<T>::from_request(req).await?;
value.validate()?;
Ok(ValidatedRequest(value))
}
}
I'm still getting the same error even with your solution
`?` couldn't convert the error to `ServerError`
--> src/shared/api_response.rs:229:61
|
229 | let Json(value) = Json::<T>::from_request(req).await?;
| ^ the trait `std::convert::From<JsonRejection>` is not implemented for `ServerError`
|```