Closed marclave closed 10 months ago
The errors at openapi
and info
, might be because the client does not support this version. If you click on the Try our new Editor
button on their website, these two errors would not appear. This is also true for this error:
Structural error at paths./todo/search/{query}.get.parameters.1.schema.type
should be string
The other errors related to AppError
not being included in components
structure, seem to show a bug with default_response_with
?
The errors at
openapi
andinfo
, might be because the client does not support this version. If you click on theTry our new Editor
button on their website, these two errors would not appear. This is also true for this error:Structural error at paths./todo/search/{query}.get.parameters.1.schema.type should be string
The other errors related to
AppError
not being included incomponents
structure, seem to show a bug withdefault_response_with
?
Yeah I think it's a bug with default_response_with since it doesn't get rendered in the schemas :)
@marclave Quick fix for now:
implement OperationOutput
for AppError
impl aide::OperationOutput for AppError {
type Inner = Self;
fn operation_response(
ctx: &mut aide::gen::GenContext,
operation: &mut aide::openapi::Operation,
) -> Option<aide::openapi::Response> {
<axum::Json<AppError> as aide::OperationOutput>::operation_response(ctx, operation)
}
fn inferred_responses(
ctx: &mut aide::gen::GenContext,
operation: &mut aide::openapi::Operation,
) -> Vec<(Option<u16>, aide::openapi::Response)> {
if let Some(res) = Self::operation_response(ctx, operation) {
vec![(None, res)]
} else {
Vec::new()
}
}
}
Note: vec![(None, res)]
, the None
here means status code can be any status code, in other words, a default
response.
In main
use aide::gen::all_error_responses(true)
Use custom extractors, with axum_macros like so:
#[derive(FromRequestParts, OperationIo)]
#[from_request(via(axum::extract::Path), rejection(AppError))]
#[aide(
input_with = "axum::extract::Path<T>",
// output_with = "axum::extract::Path<T>", // not needed for path
json_schema
)]
pub struct Path<T>(pub T);
Use Results on your routes like so:
async fn my_route(Path(input): Path<MyRouteInput>) -> impl IntoApiResponse {
// you can retrun Ok(axum::Json(YourType));
// YourType must implement `OperationOutput` if not using `axum::Json`
Return Err(AppError::new("error"));
// ofc you use other error types with their own `OperationOutput` implementation
}
Note axum::Json
is used. I don't see a value in using the Json
, in the example, as an output, but it is definitely useful as an input.
Amazing! Thanks so much
I am not sure if there is a reason default_response_with
doesn't add a schema in components. Is it intentional?
An ugly modification of default_response_with
, could be a breaking change:
pub fn default_response_with<R, F>(mut self, transform: F) -> Self
where
R: OperationOutput + JsonSchema,
F: Fn(TransformResponse<R::Inner>) -> TransformResponse<R::Inner> + Clone,
{
if let Some(p) = &mut self.api.paths {
for (_, p) in &mut p.paths {
let p = match p {
ReferenceOr::Reference { .. } => continue,
ReferenceOr::Item(p) => p,
};
for (_, op) in iter_operations_mut(p) {
let _ = TransformOperation::new(op)
.default_response_with::<R, F>(transform.clone());
}
}
}
if let Some(c) = &mut self.inner_mut().components {
let mut schema = in_context(|ctx| {
// ctx.schema.subschema_for::<R>()
ctx.schema.root_schema_for::<R>()
});
let name = schema.schema.metadata().title.as_ref().unwrap().clone();
// let name = type_name::<R>().to_owned();
c.schemas.insert(
name,
crate::openapi::SchemaObject {
json_schema: schemars::schema::Schema::Object(schema.schema),
example: None,
external_docs: None,
},
);
}
self
}
Honestly, not a big fan of TransformOperation
and friends, they add so much confusion. The OperationOutput
and OperationInput
traits way of doing things make much more sense to me.
Edited. it is indeed not the examples responsibility to set the schema, will post a fix tomorrow.
if extract shema is set to false in the example it works. The bug comes from Jsonschema that knows it must extract the schema and it thinks it is already being extracted somewhere else and thus just places the rest.
Well, turns out it was in finish_api_with
, the generated paths were necessary for applying the default responses, but the schema extraction and context reset happened before the trasform function was applied.
Fix is in master.
great library! I noticed for the example swagger spec, it renders the spec below. However, the
AppError
response is undefined in the rendering of Redocly + Swagger UI since AppError doesnt exist inside of the Schemas for the OAS specthere's also more errors on https://editor.swagger.io