What’s new in NestJS Swagger 4 ?

Kamil Mysliwiec | Trilon Consulting
Kamil Mysliwiec

Today I am excited to announce the new major release of NestJS Swagger package (@nestjs/swagger). This release brings lots of great features and long-awaited bug fixes. There are far too many to list, but let’s take a high-level look at some of the most exciting ones!

In case you're not familiar with NestJS, it is a TypeScript Node.js framework that helps you build enterprise-grade efficient and scalable Node.js applications.

Support for OpenAPI 3.0

The new version implements the OAS 3.0 specification which not only introduces a new, more simplified structure, but also, provides several great features like, for instance, support for: oneOf, anyOf and not in JSON schema and enhanced security definitions.

25 Bug Fixes & Refactors

In order to meet the needs of the community, we decided to fully refactor the codebase to make it easier to contribute to and maintain in the future. In addition, we have fixed various minor issues and therefore were able to close 25 pending issues.

Introducing the NEW Nest Swagger Plugin 🚀

TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. However, some of these constraints can be addressed at compilation time.

Hint This plugin is also opt-in. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

Overview

To reduce the amount of boilerplate code required, Nest now provides a new Swagger plugin that enhances the TypeScript compilation process.

The new Swagger plugin will automatically:

  • Annotate all DTO properties with @ApiProperty unless @ApiHideProperty is used
  • Set the required property depending on the question mark (e.g. name?: string will set required: false)
  • Set the type or enum property depending on the type (supports arrays as well)
  • Set the default property based on the assigned default value
  • Set several validation rules based on class-validator decorators (if classValidatorShim set to true)
  • Add a response decorator to every endpoint with a proper status and type (response model)

Getting started with the new Plugin

In order to enable the plugin, simply open nest-cli.json (if you use Nest CLI) and add the following plugins configuration:

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger/plugin"]
  }
}

If you don't use the CLI, you can find more instructions here.

New Plugin Features

Let's take a look at how we currently handle Swagger integrations and dive into how the plugin can now automatically handle them for us.

Data Transfer Objects

Previously, if you wanted to provide an interactive experience with the Swagger UI, you had to duplicate a lot of code to let the package knows how your models/components should be declared in the specification. For example, you could define a simple CreateUserDto class as follows:

export class CreateUserDto {
  @ApiProperty()
  email: string;

  @ApiProperty()
  password: string;

  @ApiProperty({ enum: RoleEnum, default: [], isArray: true })
  roles: RoleEnum[] = [];

  @ApiProperty({ required: false, default: true })
  isEnabled?: boolean = true;
}

While it's not a big deal with medium-sized projects, it becomes pretty verbose & clunky once you have a large set of classes.

Now, with the Swagger plugin enabled, the above class definition can be declared simply:

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  isEnabled?: boolean = true;
}
No boilerplate code anymore!

The plugin adds appropriate decorators on the fly based on the Abstract Syntax Tree. Hence, you no longer have to struggle with @ApiProperty decorators scattered throughout the entire project.

Hint The plugin will automatically generate any missing swagger properties, but if you need to override them, you simply set them explicitly via @ApiProperty() manually.

Responses

Likewise, without additional help, @nestjs/swagger cannot automatically define responses of your endpoints. Even though we could potentially leverage design:returntype metadata to get a type reference to a return type of certain method, this won't work when your handlers become asynchronous (because Promise is a generic type and there is no metadata about generics).

As a result, this is what we had to so far:

@Post()
@ApiResponse({ status: 201, type: Cat })
async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
  return this.catsService.create(createCatDto);
}

With the Swagger plugin enabled, we can simply remove @ApiResponse call:

@Post()
async create(@Body() createCatDto: CreateCatDto): Promise<Cat> {
  return this.catsService.create(createCatDto);
}

The plugin will extract the return type from the method signature and store this metadata out-of-the-box.

Migration guide

In order to migrate your existing project, follow the guidelines available here.


Support

Nest is an MIT-licensed open source project with its ongoing development made possible thanks to the support by the community, thank you!

If you want to join them, you can find more here.

Official consulting

Our goal is to help elevate teams — giving them the push they need to truly succeed in today’s ever-changing tech world. Contact us to find out more about expertise consulting, code reviews, architectural support, on-site enterprise workshops, trainings, and private sessions: support@nestjs.com.

Thank you

To all backers, sponsors, contributors, and community, thank you once again! This product is for you. And this is only the beginning of the long 🚀 story.

Become a Backer or Sponsor to Nest by donating to our open collective. ❤

#NestJS
#NodeJS

Share this Post!

📬 Trilon Newsletter

Stay up to date with all the latest Articles & News!

More from the Trilon Blog .

Michael Hladky | Trilon Consulting
Michael Hladky

Dealing with Late Subscribers in RxJS

Learn several ways to handle incoming Rx values that arrive before a Subscription has happened.

Read More
Kamil Mysliwiec | Trilon Consulting
Kamil Mysliwiec

Announcing the Official NestJS Course

Announcing the Official NestJS Course - Learn all the fundamentals of NestJS in this hands-on 5+ hour course from the NestJS creator and core team members themselves!

Read More
Kamil Mysliwiec | Trilon Consulting
Kamil Mysliwiec

Introducing Mapped Types for NestJS

Learn about the new NestJS Mapped Types and how to use them to drastically reduce the amount of boilerplate code required.

Read More

What we do at Trilon .

At Trilon, our goal is to help elevate teams - giving them the push they need to truly succeed in today's ever-changing tech world.

Trilon - Consulting

Consulting .

Let us help take your Application to the next level - planning the next big steps, reviewing architecture, and brainstorming with the team to ensure you achieve your most ambitious goals!

Trilon - Development and Team Augmentation

Development .

Trilon can become part of your development process, making sure that you're building enterprise-grade, scalable applications with best-practices in mind, all while getting things done better and faster!

Trilon - Workshops on NestJS, Node, and other modern JavaScript topics

Workshops .

Have a Trilon team member come to YOU! Get your team up to speed with guided workshops on a huge variety of topics. Modern NodeJS (or NestJS) development, JavaScript frameworks, Reactive Programming, or anything in between! We've got you covered.

Trilon - Open-source contributors

Open-source .

We love open-source because we love giving back to the community! We help maintain & contribute to some of the largest open-source projects, and hope to always share our knowledge with the world!

Explore more

Write us a message .

Let's talk about how Trilon can help your next project get to the next level.

Rather send us an email? Write to:

hello@trilon.io
© 2019-2020 Trilon, Inc.