-
Notifications
You must be signed in to change notification settings - Fork 303
Open
Description
Overview
when i use a nested type(AppResponse<PlainTreeNode<Category>>
) in response, some schemas
are missing in the generated openapi.json
.
-
AppResponse_PlainTreeNode_Category
-
Category
-
PlainTreeNode_Category
(Missing)
openapi.json
{
"openapi": "3.1.0",
"info": { "title": "utoipa-axum", "description": "Utoipa's axum bindings for seamless integration for the two", "contact": { "name": "Juha Kukkonen", "email": "[email protected]" }, "license": { "name": "MIT OR Apache-2.0", "identifier": "MIT OR Apache-2.0" }, "version": "0.2.0" },
"paths": { "/list-category": { "get": { "operationId": "list_category", "responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AppResponse_PlainTreeNode_Category" } } } } } } } },
"components": {
"schemas": {
"AppResponse_PlainTreeNode_Category": {
"type": "object",
"required": ["code", "message"],
"properties": {
"code": { "type": "integer", "format": "int64" },
"data": {
"type": "object",
"required": ["key", "children"],
"properties": { "children": { "type": "array", "items": { "$ref": "#/components/schemas/PlainTreeNode_Category" } }, "data": { "type": "object", "required": ["code", "name"], "properties": { "code": { "type": "string" }, "name": { "type": "string" } } }, "key": { "type": "string" } }
},
"message": { "type": "string" }
}
},
"Category": { "type": "object", "required": ["code", "name"], "properties": { "code": { "type": "string" }, "name": { "type": "string" } } }
}
}
}
Reproduce
[dependencies]
axum = { version = "0" }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
utoipa = { version = "5.4.0", features = ["axum_extras"] }
utoipa-axum = { version = "0.2.0" }
utoipa-swagger-ui = { version = "9.0.2", features = ["axum", "vendored"] }
#[derive(serde::Serialize, serde::Deserialize, utoipa::ToSchema)]
pub struct AppResponse<T = ()> {
pub code: i64,
pub message: String,
pub data: Option<T>,
}
#[derive(serde::Serialize, serde::Deserialize, utoipa::ToSchema)]
struct PlainTreeNode<T> {
key: String,
data: Option<T>,
#[schema(no_recursion)]
children: Vec<PlainTreeNode<T>>,
}
#[derive(serde::Serialize, serde::Deserialize, utoipa::ToSchema)]
pub struct Category {
pub code: String,
pub name: String,
}
#[utoipa::path(get, path = "/list-category", responses((status = 200, body = AppResponse<PlainTreeNode<Category>>)))]
async fn list_category() -> axum::Json<AppResponse<PlainTreeNode<Category>>> {
todo!()
}
#[tokio::main]
async fn main() {
let (router, api) = utoipa_axum::router::OpenApiRouter::new().routes(utoipa_axum::routes!(list_category)).split_for_parts();
let router = router.merge(utoipa_swagger_ui::SwaggerUi::new("/swagger-ui").url("/api/openapi.json", api));
let app = router.into_make_service();
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
axum::serve(listener, app).await.unwrap()
}
cargo run
Try to fix
add the missing type PlainTreeNode<Category>
to arg:
#[utoipa::path(get, path = "/list-category", responses((status = 200, body = AppResponse<PlainTreeNode<Category>>)))]
async fn list_category(
axum::Json(req): axum::Json<PlainTreeNode<Category>>,
) -> axum::Json<AppResponse<PlainTreeNode<Category>>> {
todo!()
}
openapi.json
{
"openapi": "3.1.0",
"info": { "title": "utoipa-axum", "description": "Utoipa's axum bindings for seamless integration for the two", "contact": { "name": "Juha Kukkonen", "email": "[email protected]" }, "license": { "name": "MIT OR Apache-2.0", "identifier": "MIT OR Apache-2.0" }, "version": "0.2.0" },
"paths": {
"/list-category": {
"get": {
"operationId": "list_category",
"requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlainTreeNode_Category" } } }, "required": true },
"responses": { "200": { "description": "", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AppResponse_PlainTreeNode_Category" } } } } }
}
}
},
"components": {
"schemas": {
"AppResponse_PlainTreeNode_Category": {
"type": "object",
"required": ["code", "message"],
"properties": {
"code": { "type": "integer", "format": "int64" },
"data": {
"type": "object",
"required": ["key", "children"],
"properties": { "children": { "type": "array", "items": { "$ref": "#/components/schemas/PlainTreeNode_Category" } }, "data": { "type": "object", "required": ["code", "name"], "properties": { "code": { "type": "string" }, "name": { "type": "string" } } }, "key": { "type": "string" } }
},
"message": { "type": "string" }
}
},
"Category": { "type": "object", "required": ["code", "name"], "properties": { "code": { "type": "string" }, "name": { "type": "string" } } },
"PlainTreeNode_Category": {
"type": "object",
"required": ["key", "children"],
"properties": { "children": { "type": "array", "items": { "$ref": "#/components/schemas/PlainTreeNode_Category" } }, "data": { "type": "object", "required": ["code", "name"], "properties": { "code": { "type": "string" }, "name": { "type": "string" } } }, "key": { "type": "string" } }
}
}
}
}
Metadata
Metadata
Assignees
Labels
No labels