Skip to content

feat(swagger): add OpenAPI 3.2 hierarchical tags support#3725

Open
apt-bh wants to merge 1 commit intonestjs:masterfrom
apt-bh:feat/openapi-v32-hierarchical-tags
Open

feat(swagger): add OpenAPI 3.2 hierarchical tags support#3725
apt-bh wants to merge 1 commit intonestjs:masterfrom
apt-bh:feat/openapi-v32-hierarchical-tags

Conversation

@apt-bh
Copy link

@apt-bh apt-bh commented Feb 5, 2026

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?

This PR implements the feature I requested in #3607. I wanted to give it a try myself.

Currently, TagObject only supports name, description, and externalDocs. OpenAPI 3.2 introduced hierarchical tags via parent and kind fields (doc here ), but there's no way to use them with @nestjs/swagger.

What is the new behavior?

  • TagObject interface now includes optional parent and kind fields
  • DocumentBuilder.addTag() accepts an optional 4th parameter for hierarchy options
  • @ApiTags decorator accepts object form { name, parent?, kind? } alongside strings
  • New ApiTagOptions type is exported for TypeScript users
// Define tag hierarchy at document level
const config = new DocumentBuilder()
  .addTag('Animals', 'All animal operations')
  .addTag('Cats', 'Cat operations', undefined, { parent: 'Animals' })
  .addTag('Dogs', 'Dog operations', undefined, { parent: 'Animals', kind: 'navigation' })
  .build();

// Use @ApiTags with object form for hierarchy
@ApiTags({ name: 'Cats', parent: 'Animals' })
@Controller('cats')
export class CatsController {}

// Or mix strings and objects
@ApiTags('Dogs', { name: 'Puppies', parent: 'Dogs' })
@Controller('puppies')
export class PuppiesController {}

// Existing string syntax remains fully supported
@ApiTags('Cats')
@Controller('cats')
export class CatsController {}

Note: The hierarchy info (parent, kind) is only meaningful at the document level. When using @ApiTags with objects, the name is extracted for operation-level tags (which are always string[] per OpenAPI spec), while the full hierarchy should be defined via DocumentBuilder.addTag().

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

OpenAPI version compatibility: The parent and kind fields are part of the OpenAPI 3.2 specification. Tools that only support OpenAPI 3.0/3.1 will simply ignore these fields, so this feature is fully backward compatible.

Closes #3607

Add support for the `parent` and `kind` fields on TagObject as introduced
in OpenAPI 3.2. This allows users to organize tags hierarchically for
better documentation navigation in large APIs.

Changes:
- Extend TagObject interface with optional `parent` and `kind` fields
- Add new ApiTagOptions type for decorator usage
- Extend DocumentBuilder.addTag() to accept hierarchy options
- Update @apitags decorator to accept object form alongside strings
- Add comprehensive unit and e2e tests

Usage:
```typescript
// Document-level hierarchy
new DocumentBuilder()
  .addTag('Animals', 'All animal operations')
  .addTag('Cats', 'Cat operations', undefined, { parent: 'Animals' })
  .build();

// Decorator still works with strings (backward compatible)
@apitags('Cats')
```

Closes nestjs#3607
@apt-bh apt-bh mentioned this pull request Feb 5, 2026
1 task
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.

OpenAPI v3.2 Hierarhical tags

1 participant