Replies: 3 comments 2 replies
-
Seems that the most correct is to specify each schema with an const UserSchema = t.Object({
name: t.String()
}, {
$id: "User"
}) And then put this schema object directly into Single: response: t.Object({
user: t.Ref(UserSchema)
}) Multiple: response: t.Object({
users: t.Array(t.Ref(UserSchema))
}) This seems to generate the following OpenAPI document: Show
Components section: "components": {
"schemas": {
"User": {
"$id": "User",
"type": "object",
"properties": {
"name": { "type": "string" }
},
"required": [
"name"
]
}
}
} Paths section: "paths": {
"/users/": {
"get": {
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"users": { "type": "array", "items": { "$ref": "User" } }
},
"required": ["users"]
}
}
}
}
},
"operationId": "getUsers",
"summary": "Get all users"
}
},
"/users/{id}": {
"get": {
"parameters": [
{
"anyOf": [
{ "format": "numeric", "default": 0, "type": "string" },
{ "type": "number" }
],
"schema": {},
"in": "path",
"name": "id",
"required": true
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": { "user": { "$ref": "User" } },
"required": ["user"]
}
}
}
}
},
"operationId": "getUsersById",
"summary": "Get a user"
}
}
} It won't show the name of the schema up front, but it does correctly refer to it, so I guess that's just a SwaggerUI feature. The identification can be made with the This seems to be the best I can come up with for now. |
Beta Was this translation helpful? Give feedback.
-
This is a really big problem. I've tried using Elysia several times, but it seems like there's no way to work with lists/arrays. Likewise, I've tried various options, defining types via PS the manual configuration works fine, for example: const UserResponse = t.Object({ /* ... */ }, { $id: 'UserResponse' });
// the full link to the schema:
const UsersResponse = t.Array(t.Ref('#/components/schemas/UserResponse'), { $id: 'UsersResponse' });
app
.model({
UserResponse,
UsersResponse,
})
.get('/users', () => /* ... */, { response: { defualt: 'UsersResponse' }, /* ... */ })
.get('/users/:id', () => /* ... */, { response: { default: 'UserResponse' }, /* ... */ }) |
Beta Was this translation helpful? Give feedback.
-
Since I posted this, I came across a different, albeit more manual, solution that seems mostly okay. Mentioned here. I think this was made possible in a more recent version of Elysia, as I had to upgrade my dependencies for it to work. The important part is that the const PetSchema = t.Object(
{
name: t.String(),
animal: t.String(),
},
{
$id: "#/components/schemas/Pet",
}
); An array version would be like this: const PetsSchema = t.Array(t.Ref(PetSchema)); Register the (singular) schema: .model({
Pet: PetSchema
}) To refer to the singular schema, you can do it normally by just doing I think there's a fair bit of room for DX improvement here though. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
In regards to Swagger documentation, being able to use
.model
is very nice as it also generates schema components. However, I find myself wanting to re-use some of these schemas, but wrapped in an array. Essentially I want to mix pre-defined components with one-off schemas per route.How should this be achieved?
Assume I register a schema like so:
What I have tried so far, and their issues:
1. Register an array version in .model
With this, I register both the singular and the array version as 2 separate schemas.
Problem:
This will register both as schemas in the components section for SwaggerUI, which I find to be redundant, since they are more or less the same schema.
2. Manually import the schema only for the routes that require the array version
With this, I register only the singular schema, and manually import the schema only for the routes that need it in a different way
Problem:
This mixes the implementations based on whether I want a single or multiple items, since the single item will still be configured using
response: "User"
.3. Just use .model for documentation rather than auto-complete.
With this, I only register the schemas with .model, but never refer to any of them by name in the routes, instead importing the same schemas.
Problem:
This loses out on the benefit of having the auto-complete suggestions and the entire feature of registering schemas by their string name. It also makes Swagger unable to detect that it is the same schema, instead thinking it is a separate object with the same shape.
Referring to registered schema by name:

Referring to re-import of the schema object:

What I would want ideally is to do something like this (I don't think this is currently possible, but please correct me):
Is there maybe something that will solve this using
t.Ref
or so?Beta Was this translation helpful? Give feedback.
All reactions