Skip to content

feat(decorators): add style and explode options to @ApiProperty#3789

Open
JadenKim-dev wants to merge 3 commits intonestjs:masterfrom
JadenKim-dev:feat/support-deepobject-style-in-api-property
Open

feat(decorators): add style and explode options to @ApiProperty#3789
JadenKim-dev wants to merge 3 commits intonestjs:masterfrom
JadenKim-dev:feat/support-deepobject-style-in-api-property

Conversation

@JadenKim-dev
Copy link
Copy Markdown

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe:

What is the current behavior?

@ApiProperty does not accept style or explode options. When using a nested object as a query parameter (e.g. Geolocation inside a QueryDto), there is no way to specify style: 'deepObject' without a @ts-expect-error workaround.

This causes Swagger UI to generate flat query strings like ?latitude=5&longitude=1 instead of ?geolocation[latitude]=5&geolocation[longitude]=1.

Issue Number: #3495

What is the new behavior?

ApiPropertyCommonOptions now includes optional style (typed as ParameterStyle) and explode (typed as boolean) properties. These values are passed through to the OpenAPI ParameterObject at the top level, enabling proper serialization of nested query parameters.

Example usage:

@ApiProperty({
  required: false,
  type: () => GeolocationDto,
  style: 'deepObject',
  explode: true,
})
geolocation?: GeolocationDto;

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Add `style` and `explode` properties to `ApiPropertyCommonOptions`,
allowing nested object query parameters to be serialized using
OpenAPI serialization styles such as `deepObject`.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends @ApiProperty options to support OpenAPI parameter serialization (style/explode), enabling nested query DTO properties to be emitted as a single ParameterObject (e.g. style: 'deepObject') rather than flattened query params.

Changes:

  • Add style?: ParameterStyle and explode?: boolean to ApiPropertyCommonOptions.
  • Add SchemaObjectFactory tests asserting style/explode are preserved on the generated ParameterObject and that nested DTOs are not flattened.
  • Add SwaggerExplorer tests asserting nested query DTO properties emit a single query parameter with style=deepObject, explode=true, and a $ref schema.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
lib/decorators/api-property.decorator.ts Extends @ApiProperty option typings to include parameter serialization fields (style, explode).
test/services/schema-object-factory.spec.ts Adds coverage around createFromModel output for deepObject-style nested query params.
test/explorer/swagger-explorer.spec.ts Verifies explorer output for nested query DTO parameters preserves style/explode and avoids flattening.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…t metadata

style and explode are ParameterObject-only fields and should not leak
into generated SchemaObjects. Omit them alongside link when reading
API_MODEL_PROPERTIES metadata.

Also remove unused QueryDto class from the schema-object-factory test.
…support-deepobject-style-in-api-property
@JadenKim-dev
Copy link
Copy Markdown
Author

@kamilmysliwiec
All Copilot review suggestions have been addressed.

One note: after merging the latest master, the build-and-test CI action is currently failing. This appears to be caused by an upstream issue introduced in #3802 (isConstEnumObject misidentifies regular TypeScript enums as const-enum objects), which is unrelated to the changes in this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants