Closed Rolv-Apneseth closed 2 months ago
Hi,
I attempted to reproduce the issue using a minimal example with axum-valid
and aide
. The following code compiles successfully, but it may not ensure documentation generation:
use aide::axum::routing::post_with;
use aide::axum::{ApiRouter, IntoApiResponse};
use aide::openapi::OpenApi;
use aide::transform::{TransformOpenApi, TransformOperation};
use axum::extract::Query;
use axum_valid::Valid;
use schemars::JsonSchema;
use serde::Deserialize;
use tokio::net::TcpListener;
use validator::Validate;
fn api_docs(api: TransformOpenApi) -> TransformOpenApi {
api
}
#[tokio::main]
async fn main() {
let mut api = OpenApi::default();
let listener = TcpListener::bind("0.0.0.0:8888").await.unwrap();
let router = ApiRouter::new()
.api_route("/", post_with(handler, handler_docs))
.finish_api_with(&mut api, api_docs);
axum::serve(listener, router).await.unwrap();
}
#[derive(Deserialize, JsonSchema, Validate)]
struct Param {
v0: String,
}
async fn handler(Valid(Query(Param { v0 })): Valid<Query<Param>>) -> impl IntoApiResponse {
println!("v0: {v0}");
}
fn handler_docs(op: TransformOperation) -> TransformOperation {
op.description("Handler.").response::<200, ()>()
}
Cargo.toml:
[package]
name = "av-test"
version = "0.1.0"
edition = "2021"
[dependencies]
aide = { version = "0.13.4", features = ["axum"] }
axum = "0.7.5"
axum-valid = { version = "0.18.0", features = ["aide"] }
validator = { version = "0.18.1", features = ["derive"] }
schemars = "0.8.21"
serde = { version = "1.0.203", features = ["derive"] }
tokio = { version = "1.38.0", features = ["full"] }
Using a similar approach, I was able to introduce Valid
in the aide
todo example and successfully generate the documentation. Please check the dependency versions and ensure all necessary traits are derived (e.g., Validate
from validator
). Let me know if this helps or if you need further assistance!
Hey, sorry, not had much time. Thank you for the reply. The minimal example does indeed work for me.
Having looked into it further, my Query
was actually a custom extractor, and the impl
I was missing is this:
impl<T> HasValidate for Query<T> {
type Validate = T;
fn get_validate(&self) -> &T {
&self.0
}
}
I'll be sure to do this for any other custom extractors and hopefully all will be fine. Thanks again for the reply and I'll come back if I run into any other issues (though this weekend I am occupied).
Hey again. I think I've run into this again with garde
, but the previous fix I mentioned didn't work. Modifying the minimal example you provided also gives the same trait bound error:
Edit: This appears to be the same for validifiy
, hope I'm not doing something silly here but here is the same minimal example:
axum-valid 0.18.0 only support garde 0.18.0.
try this:
// main.rs
use aide::axum::routing::post_with;
use aide::axum::{ApiRouter, IntoApiResponse};
use aide::openapi::OpenApi;
use aide::transform::{TransformOpenApi, TransformOperation};
use axum::extract::Query;
use axum_valid::{Garde, Valid, Validified};
use schemars::JsonSchema;
use serde::Deserialize;
use tokio::net::TcpListener;
use validator::Validate;
fn api_docs(api: TransformOpenApi) -> TransformOpenApi {
api
}
#[tokio::main]
async fn main() {
aide::gen::on_error(|error| {
println!("{error}");
});
aide::gen::extract_schemas(true);
let mut api = OpenApi::default();
let listener = TcpListener::bind("0.0.0.0:8888").await.unwrap();
let router = ApiRouter::new()
.api_route("/validator", post_with(handler, handler_docs))
.api_route("/garde", post_with(handler_g, handler_docs))
.api_route("/validify", post_with(handler_v, handler_docs))
.finish_api_with(&mut api, api_docs);
axum::serve(listener, router).await.unwrap();
}
#[derive(Deserialize, JsonSchema, Validate)]
struct Param {
v0: String,
}
#[derive(Deserialize, JsonSchema, garde::Validate)]
struct ParamG {
#[garde(length(min = 1, max = 10))]
v0: String,
}
#[derive(Deserialize, JsonSchema, validify::Validify, validify::Payload)]
struct ParamV {
v0: String,
}
async fn handler(Valid(Query(Param { v0 })): Valid<Query<Param>>) -> impl IntoApiResponse {
println!("v0: {v0}");
}
async fn handler_g(Garde(Query(ParamG { v0 })): Garde<Query<ParamG>>) -> impl IntoApiResponse {
println!("v0: {v0}");
}
async fn handler_v(
Validified(Query(ParamV { v0 })): Validified<Query<ParamV>>,
) -> impl IntoApiResponse {
println!("v0: {v0}");
}
fn handler_docs(op: TransformOperation) -> TransformOperation {
op.description("Handler.").response::<201, ()>()
}
# Cargo.toml
[dependencies]
aide = { version = "0.13.4", features = ["axum"] }
axum = "0.7.5"
axum-valid = { version = "0.18.0", features = ["aide", "garde", "validify"] }
validator = { version = "0.18.1", features = ["derive"] }
schemars = "0.8.21"
serde = { version = "1.0.203", features = ["derive"] }
tokio = { version = "1.38.0", features = ["full"] }
garde = { version = "0.18.0", features = ["derive", "serde"] }
validify = { version = "1.4.0" }
axum-valid 0.18.0 only support garde 0.18.0.
Ah I see, my bad.
Yes that example works great, thank you again for the help, I appreciate it.
I've been a bit busy recently and haven't yet updated axum-valid to support the latest version of garde (0.20.0). I will work on this update as soon as possible.
Thanks for bringing this to my attention.
No problem, thanks for working on this. I'm just using axum
and it's ecosystem for the first time currently.
Hi, I'm currently trying to use this library in a project where I have
aide
set up, and using theaide
feature foraxum-valid
, I still get an error complaining about trait bounds not being met. Any idea why that might be?I never understand quite how to track these errors down:
Here is the relevant code:
Thank you for making and maintaining this library by the way, it seems really cool.