Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@ApiProperty - Include default value when using enumName #2898

Closed
1 task done
Eirmas opened this issue Mar 29, 2024 · 6 comments
Closed
1 task done

@ApiProperty - Include default value when using enumName #2898

Eirmas opened this issue Mar 29, 2024 · 6 comments
Labels

Comments

@Eirmas
Copy link

Eirmas commented Mar 29, 2024

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

@Eirmas Eirmas added the feature label Mar 29, 2024
@kamilmysliwiec
Copy link
Member

Would you like to create a PR for this issue?

@kimdj2
Copy link
Contributor

kimdj2 commented Mar 31, 2024

スクリーンショット 2024-03-31 11 48 09
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') },
  ]
})

@raj-r3a
Copy link

raj-r3a commented Aug 2, 2024

@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?

@arabold
Copy link

arabold commented Oct 9, 2024

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.

@0816i
Copy link

0816i commented Oct 14, 2024

I have same issue(#3101). actually The declaration doesn't disappear, but you can find its default in other schema declared enumName.

@kamilmysliwiec
Copy link
Member

#3123

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants