Nest JS — Open API Just saves so much time — Part 1
After a long search, I finally found a tool that can write my backend documentation based on the code I write. I have been looking for a reliable solution for a while now, and it has been a challenge to find a tool that meets my specific needs. However, my search came to an end when I discovered NestJS OpenAPI.
NestJS:
NestJS provides a number of features and benefits that are particularly useful for building backend applications. For example, it offers a modular architecture that allows developers to organize their code into small, reusable modules that can be easily tested and maintained. Additionally, it provides a range of built-in modules and libraries that can help developers quickly implement common features such as authentication, caching, and database connectivity.
OpenAPI:
OpenAPI, previously known as Swagger, is a specification for building APIs. It provides a standardized and language-agnostic way to describe RESTful APIs, making it easier for developers to understand and interact with APIs. OpenAPI is becoming increasingly popular in the development community, and many frameworks, including NestJS, have built-in support for it.
In NestJS, OpenAPI can be used to automatically generate API documentation based on the code that developers write. This can save a significant amount of time and effort that would otherwise be spent manually documenting each API endpoint. NestJS’s integration with OpenAPI allows developers to easily define the structure and parameters of their API endpoints using decorators, which are then used to generate API documentation automatically. This ensures that the API documentation remains accurate and up-to-date, even as the code changes.
Another useful feature of OpenAPI in NestJS is the ability to validate API requests and responses. OpenAPI provides a schema for describing the structure and data types of request and response payloads. By using this schema, NestJS can automatically validate incoming requests and outgoing responses, ensuring that they conform to the expected format. This can help prevent errors and improve the overall reliability of the API.
Installation:
Create a new NestJS project or navigate to an existing NestJS project in your terminal.
Install the @nestjs/swagger
package by running the following command:
npm install --save @nestjs/swagger
Update your main.ts file:
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder()
.setTitle('Cats example')
.setDescription('The cats API description')
.setVersion('1.0')
.addTag('cats')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
await app.listen(3001);
}
bootstrap();
Right after starting your nest application, You can access the API documentation by opening your web browser and navigating to http://localhost:3001/api:
Once we have completed all the previous steps, we will be able to proceed with implementing the OpenAPI specification in our requests.
Adding A new resource:
The Nest CLI (Command Line Interface) is a powerful tool that is used to generate and manage Nest applications. It provides a set of commands that allow developers to quickly scaffold a new project, generate components such as controllers and services, and run the application.
Now we need to make a new resource we will use the next command:
nest g resource employee
When we use this command the CLI will generate a new module for your resource, along with a controller, service, and a test file.
You should see an employee folder inside src folder that looks like:
Employee resource folder
Now lets make a new Dto for Employee, lets create a dto folder inside employee to hold all employee dto’s. and the lets make a new file calls index.ts like this…
Lets add some content to the index.ts file:
import { ApiProperty, ApiResponseProperty } from '@nestjs/swagger';
export class EmployeeDTO {
@ApiResponseProperty()
id?: number;
@ApiProperty()
first_name: string;
@ApiProperty()
last_name: string;
}
@ApiProperty — As you can see, the definition is empty although the class has a few declared properties. In order to make the class properties visible to the SwaggerModule, we have to either annotate them with the @ApiProperty() decorator or use the CLI plugin (read more in the Plugin section) which will do it automatically
Now when all set its time to make it works with our controllers.
Types and parameters
The SwaggerModule searches for all @Body(), @Query(), and @Param() decorators in route handlers to generate the API document. It also creates corresponding model definitions by taking advantage of reflection.
Lets start Edit our employee’s controller!!
We are gonna add a new method and call her create — this method will create a new Employee by the EmployeeDTO template and add it to the Employees Array
import { Body, Controller, Post } from '@nestjs/common';
import { ApiResponse, ApiTags } from '@nestjs/swagger';
import { EmployeeDTO } from './dto';
import { EmployeeService } from './employee.service';
@Controller('employee')
@ApiTags('employee')
export class EmployeeController {
constructor(private readonly employeeService: EmployeeService) {}
@Post()
@ApiResponse({
status: 201,
type: EmployeeDTO,
})
createEmployee(@Body() employeeDto: EmployeeDTO) {
return {...employeeDto,id:Date.now()};
}
}
If we Check our open-api docs again we will see that things have changes. a new Api tag has added, a new POST method has been created and a new Employee Type.
Lets Open our generated employee’s POST Method:
We can see that the body and the Response has already generated with out defined “EmployeeDTO” type. But there is another question, why is The Request Body and The response are showed different if they are from the same type?
The answer is @ApiResponseProperty(), When we define a property with this tag that actual property will be shown only at the Response that we defined in our controller.
Let’s learn another new cool decorators who are really useful:
@ApiOperation() — Add a summary and description to your API Method:
Add the “ApiOperation” Decorator to our employee’s controller like in the following example:
@Controller('employee')
@ApiTags('employee')
export class EmployeeController {
constructor(private readonly employeeService: EmployeeService) {}
@Post()
@ApiOperation({
summary: 'Create new Employee',
description: 'Lorem ipsum ....',
})
@ApiResponse({
status: 201,
type: EmployeeDTO,
})
createEmployee(@Body() employeeDto: EmployeeDTO) {
return { ...employeeDto, id: Date.now() };
}
}
The @ApiOperation decorator is used to provide metadata about the operation (HTTP endpoint) that the method handles. It takes an object with properties such as summary and description that describe the operation. In this case, the createEmployee() method is used to create a new employee, so the @ApiOperation decorator is used to provide a summary and description of the operation.
If we Check our open-api docs again we will see that our summary and description has been added.
@ApiProperty() — Extra configuration!!
Usually when we build api we use validations to make sure that our properties are receives as expected. In nestjs Open api we can describe our Validations.
Lets edit our index.ts file inside dto folder like the following example:
export class EmployeeDTO {
@ApiResponseProperty()
id?: number;
@ApiProperty({
description: 'The first name of a employee',
minLength: 3,
default: 'Amit',
})
first_name: string;
@ApiProperty({
description: 'The first name of a employee',
minLength: 2,
default: 'Gal',
})
last_name: string;
}
As we can see we configured our ApiProperty decorator for each property. for example first_name description is ‘The first name of a employee’ min-length is 3 and the value will be default ‘amit’.
Now if we check our schemas on the bottom on the Doc-Page we will see that our properties received their doc.
In conclusion, NestJS OpenAPI is a highly effective tool that streamlines API development and documentation. In this article you have learned just a bit about Open Api in Nests.