@ApiProperty - Include default value when using `enumName`
Eirmas opened this issue · 6 comments
Is there an existing issue that is already proposing this?
- I have searched the existing issues
Is your feature request related to a problem? Please describe it
When using @ApiProperty
like this:
@ApiProperty({ enum: SortOrder, default: SortOrder.DESC })
It renders the OpenAPI json like this:
{
"name": "order",
"required": true,
"in": "query",
"schema": {
"default": "DESC",
"enum": [
"DESC",
"ASC"
],
"type": "string"
}
}
However, when adding a reference to the enum using enumName
instead to avoid duplicate definitions like this:
@ApiProperty({ enum: SortOrder, default: SortOrder.DESC, enumName: 'SortOrder' })
It renders like this:
{
"name": "order",
"required": true,
"in": "query",
"schema": {
"$ref": "#/components/schemas/SortOrder"
}
}
Here we can see that the default
property is lost.
Describe the solution you'd like
Here is a discussion that explains a possible solution: OAI/OpenAPI-Specification#2948
Teachability, documentation, adoption, migration strategy
No response
What is the motivation / use case for changing the behavior?
Improve user experience when using software like Postman, Swagger or similar
Would you like to create a PR for this issue?
ref: https://swagger.io/docs/specification/using-ref/
In v3.1.0, it appears that you can define some sibling elements, but it still don't have default
property.
ref: https://spec.openapis.org/oas/v3.1.0#reference-object
OAI/OpenAPI-Specification#2948
In my opinion, the example in this page is no different than the code below.
@ApiProperty({
default: SortOrder.DESC,
allOf: [
{ $ref: getSchemaPath('SortOrder') },
]
})
@Eirmas , you are right, but the SortOrder schema has the default added there and it is being rendered in the swagger ui as well.
@kamilmysliwiec , I am looking to contribute, Is there any priority on the issues that I can start with?
I've ended up patching @nestjs/swagger
like this:
diff --git a/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js b/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js
index b5c6978..dd9883a 100644
--- a/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js
+++ b/node_modules/@nestjs/swagger/dist/services/schema-object-factory.js
@@ -167,16 +167,16 @@ class SchemaObjectFactory {
}
const enumName = metadata.enumName;
const $ref = (0, utils_1.getSchemaPath)(enumName);
- const additionalParams = ['description', 'deprecated', 'default'];
+ const additionalParams = ['description'];
const additionalFields = additionalParams.reduce((acc, param) => (Object.assign(Object.assign({}, acc), (metadata[param] && { [param]: metadata[param] }))), {});
const enumType = (_a = (metadata.isArray ? metadata.items['type'] : metadata.type)) !== null && _a !== void 0 ? _a : 'string';
schemas[enumName] = Object.assign(Object.assign({ type: enumType }, additionalFields), { enum: metadata.isArray && metadata.items
? metadata.items['enum']
: metadata.enum });
const _schemaObject = Object.assign(Object.assign({}, metadata), { name: metadata.name || key, type: metadata.isArray ? 'array' : 'string' });
- const refHost = metadata.isArray ? { items: { $ref } } : { $ref };
+ const refHost = metadata.isArray ? { items: { $ref } } : { allOf: [{$ref}] };
const paramObject = Object.assign(Object.assign({}, _schemaObject), refHost);
- const pathsToOmit = ['enum', 'enumName', ...additionalParams];
+ const pathsToOmit = ['enum', 'enumName'];
if (!metadata.isArray) {
pathsToOmit.push('type');
}
This change will wrap the $ref
in an allOf
as previously suggested and retain properties like description
, deprecated
and default
as expected.
Unfortunately there's no way of documenting the enum itself, so this code copies the description from the property to the enum schema definition. This is still the original behavior.