Para que Swagger encuentre tus DTOs y Entities es necesario tener los archivos con extension .dto.ts
y .entity.ts
repectivamente
Módulos de NestJS
¿Ya tomaste el Curso de Backend con NestJS?
Encapsular lógica en módulos
Overview del proyecto: PlatziStore
Interacción entre módulos
Entendiendo la inyección de dependencias
useValue y useClass
useFactory
Global Module
Configuración de entornos
Módulo de configuración
Configuración por ambientes
Tipado en config
Validación de esquemas en .envs con Joi
Documentación
Integrando Swagger y PartialType con Open API
Extendiendo la documentación
Deploy
Configuración de Heroku
Deploy de NestJS en Heroku
Próximos pasos
Continúa con los cursos de persistencia de datos en NestJS
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Una API profesional debe estar documentada. Cuando hablamos de documentación, nos suena a una tarea tediosa que nadie quiere realizar. Afortunadamente, NestJS permite automatizar fácilmente la creación de la misma.
Swagger es un reconocido set de herramientas para la documentación de API Rest. Instala las dependencias necesarias con el comando npm install --save @nestjs/swagger swagger-ui-express
y configura el archivo main.ts
con el siguiente código.
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Configuración Swagger en NestJS
const config = new DocumentBuilder()
.setTitle('Platzi API')
.setDescription('Documentación Platzi API')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
// URL API
SwaggerModule.setup('docs', app, document);
await app.listen(process.env.PORT || 3000);
}
bootstrap();
Setea el título, descripción y versión de tu documentación. Lo más importante es la URL para acceder a la misma.
Levanta el servidor con npm run start:dev
y accede a localhost:3000/docs
para visualizar la documentación autogenerada que mapea automáticamente todos los endpoints de tu aplicación.
La documentación autogenerada por Swagger es bastante simple, puedes volverla más completa tipando los datos de entrada y salida de cada endpoint gracias a los DTO.
Busca el archivo nest-cli.json
en la raíz de tu proyecto y agrega el siguiente plugin:
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compileOptions": {
"plugins": ["@nestjs/swagger"]
}
}
A continuación, prepara tus DTO de la siguiente manera:
import { IsNotEmpty, IsString, IsNumber } from 'class-validator';
import { ApiProperty, PartialType, OmitType } from '@nestjs/swagger';
export class CreateProductDTO {
@ApiProperty()
@IsNotEmpty()
@IsString()
readonly name: string;
@ApiProperty()
@IsNotEmpty()
@IsString()
readonly description: string;
@ApiProperty()
@IsNotEmpty()
@IsNumber()
readonly price: number;
}
export class UpdateAuthorDto extends PartialType(
OmitType(CreateProductDTO, ['name']),
) {}
Lo más relevante aquí es importar PartialType y OmitType desde @nestjs/swagger
en lugar de importarlo desde @nestjs/mapped-types
. Coloca también el decorador @ApiProperty()
en cada una de las propiedades que el DTO necesita.
De esta manera, observarás en la documentación que indica el tipo de dato que requiere cada uno de tus endpoints.
npm install --save @nestjs/swagger swagger-ui-express
// src/main.ts
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
async function bootstrap() {
...
const config = new DocumentBuilder()
.setTitle('API')
.setDescription('PLATZI STORE')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, document);
...
await app.listen(3000);
}
bootstrap();
# nest-cli.json
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"plugins": ["@nestjs/swagger/plugin"]
}
}
// src/products/dtos/brand.dtos.ts
import { PartialType } from '@nestjs/swagger';
// src/products/dtos/category.dtos.ts
import { PartialType } from '@nestjs/swagger';
// src/products/dtos/products.dtos.ts
import { PartialType } from '@nestjs/swagger';
// src/users/dtos/customer.dto.ts
import { PartialType } from '@nestjs/swagger';
// src/users/dtos/user.dto.ts
import { PartialType } from '@nestjs/swagger';
Contribución creada por: Kevin Fiorentino.
Aportes 30
Preguntas 19
Para que Swagger encuentre tus DTOs y Entities es necesario tener los archivos con extension .dto.ts
y .entity.ts
repectivamente
Buenas por si a alguien más le pasa hice toda la configuración como el profesor pero los dtos no me reflejaban bien en la documentación solo los entities al mirar en la documentación me di cuenta que ellos le añaden otro decorador más a los dtos. @ApiProperty()
https://docs.nestjs.com/openapi/mapped-types
Aquí dejo un ejemplo de como quedaría un dto:
import { IsString, IsUrl, IsNotEmpty } from 'class-validator';
import { PartialType, ApiProperty } from '@nestjs/swagger';
export class CreateBrandDto {
@ApiProperty()
@IsString()
@IsNotEmpty()
readonly name: string;
@ApiProperty()
@IsUrl()
@IsNotEmpty()
readonly image: string;
}
export class UpdateBrandDto extends PartialType(CreateBrandDto) {}
´´´
Para los que no les funciona el swagger, se debe actualizar el repositorio
nest update -f -t latest
Si tienes fallos, intenta con swagger 4.
npm i @nestjs/swagger@4.5.12-next.1
No entiendo por qué tengo errores con la ultima versión ‘Swagger 5’, así que esto es una alternativa.
Si estás usando el repo del profesor con Nest v7, seguramente tendrás que hacer:
npm i --save @nestjs/swagger@4.7.16 swagger-ui-express@4.1.6 --legacy-peer-deps
Si como yo estan usando Fastify, necesitan instalar:
npm install --save @nestjs/swagger fastify-swagger
yarn:
yarn add @nestjs/swagger fastify-swagger
Para que Swagger reconozca las DTOs es necesario borrar la carpeta dist y correr de nuevo el proyecto.
En Git Bash / Linux:
rm -rf dist
Me funciono fue esta version npm i @nestjs/[email protected] swagger-ui-express
si tratan de hacer el ejercicio al día de hoy, deben actualizar esta dependencia si tiene problemas.
@nestjs/platform-express
Está muy buena la documentación que genera Swagger! muy facil.
Creo que ya me gustó más Nest que Express… Solo por esto
Para los que integren al Nest CLI el plugin de Swagger, les recomiendo no usar caracteres especiales en sus directorios.
Si les aparece el error:
Module Not Found
Lo más probable es que en algún lugar de su directorio tengan alguno. En mi caso fue un acento. Pues bautice mi carpeta raíz como:
programación-modular
No fue hasta que buscando la causa del error, encontré la respuesta en GitHub Issues:
10/07/2022.
Al instalar Swagger tanto con el comando que usa Nico como el comando que aparece en la documentacion oficial de Nestjs, me tiro errores. A continuacion dejo los pasos sobre como resolvi el error por si a algun otro le sucede lo mismo.
Para instalar swagger usamos el comando:
$ npm install --save @nestjs/swagger
Al instalar Swagger tira conflictos de dependencias.
Primero dependencia @nestjs/common deprecada. Cuando lo actualizas, luego aparece @nestjs/core deprecada.
Por lo que al final, procedo a actualizar las dependencias en general de nestjs, por las dudas.
Comando:
$ nest update --force
▹▹▹▹▹ Installation in progress… ☕▹▹▹▹▹ Package install
▹▸▹▹▹ Installation in progress… ☕
Failed to execute command: npm install --save @nestjs/axios@latest @nestjs/common@latest @nestjs/config@latest @nestjs/core@latest @nestjs/mapped-types@latest @nestjs/platform-express@latest
✖ Package installation in progress… ☕
✔ Installation in progress… ☕
Sale error de que no se pudo ejecutar la cadena de comandos para actualizar dependencias (probablemente haya error en alguna de todas las dependencias que se muestra que se esta queriendo actualizar). Por lo que procedo a actualizar manualmente, una a una para verificar cual tira error.
$ npm install --save @nestjs/axios@latest (✔)
$ npm install --save @nestjs/common@latest (✔)
$ npm install --save @nestjs/config@latest (✔)
$ npm install --save @nestjs/core@latest (✖ tira error)
$ npm install --save @nestjs/mapped-types@latest (✔)
$ npm install --save @nestjs/platform-express@latest (✖ tira error)
Una vez identificado las dependencias que generan conflicto vemos que @nestjs/platform-express@latest depende de tener @nestjs/core actualizada y a su vez descubrimos que @nestjs/core@latest depende de tener @nestjs/testing actualizada.
por lo que se procede a instalar en orden esas dependencias:
$ npm install --save @nestjs/testing@latest
$ npm install --save @nestjs/core@latest
$ npm install --save @nestjs/platform-express@latest
y vemos que ahora instalan y actualizan correctamente.
Para asegurarnos de actualizar correctamente todas las dependencias, le damos de vuelta al comando: nest update --force (no debería tener conflictos ahora):
$ nest update --force
Y vemos que finaliza la actualización de manera satisfactoria.
Al final, procedemos a instalar Swagger (de paso instalamos la ultima versión):
$ npm install --save @nestjs/swagger@latest
Y vemos que se instala sin problemas.
Nota: Al final, el problema era que al actualizar nestjs con el comando: nest update --force , faltaba @nestjs/testing@latest antes del @nestjs/core@latest .
La solución era que se debía haber introducido la siguiente secuencia de comandos manual :
$ npm install --save @nestjs/axios@latest @nestjs/common@latest @nestjs/config@latest @nestjs/testing@latest @nestjs/core@latest @nestjs/mapped-types@latest @nestjs/platform-express@latest
npm install --save @nestjs/swagger swagger-ui-express
nest-cli.js
{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"plugins": ["@nestjs/swagger"]
}
}
main.ts
se agrega la configuracion de swagger antes de listen del serverconst config = new DocumentBuilder()
.setTitle('API')
.setDescription('Store')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, document);
import { PartialType } from '@nestjs/swagger';
Borramos la carpeta dist rm -rf dist
o click derecho borrar carpeta
Ejecutamos la aplicacion npm run start:dev
Hay otra manera de extender las propiedades de un dto y seleccionar las que si son obligatorias. Imaginemos el escenario yo tengo un dto que tiene el modelo de un producto, necesito un dto que contenga el modelo de las unidades de un producto comprado y solo algunos datos del producto (id, nombre).
Defino el DTO de producto (padre)
import { ApiProperty } from '@nestjs/swagger';
export class ProductResponseDto {
@IsString()
@IsNotEmpty()
@ApiProperty({ description: 'Product Id' })
id: string;
@IsString()
@IsNotEmpty()
@ApiProperty({ description: "Product's Name", example: 'Uniforme marca Titin' })
@Expose()
name: string;
@IsString()
@IsNotEmpty()
@ApiProperty({ description: "Product's Sku", example: 'RBLL005' })
@Expose()
sku: string;
@IsString()
@ApiProperty({
description: "Product's Description",
example: 'American Drink',
})
@Expose()
description: string;
}
DTO de producto comprado (hijo)
import { ApiProperty, PickType } from '@nestjs/swagger';
class ProductSaleResponseDto extends PickType(ProductResponseDto , [
'id',
'name',
]) {
@IsNumber()
@IsPositive()
@ApiProperty({ description: 'Quantity product buy' })
quantity: number;
}
Mas clean no puede ser este seccion de cursos de NestJS 👌💚
Para no estar eliminando la carpeta /dist constantemente con el comando
rm -rf dist
Podemos activar la eliminación automática de la carpeta cada vez que se invoque al compilador ejecutando npm run start:dev colocando
"deleteOutDir": true
dentro de nuestro nest-cli.json quedando de la siguiente manera:
"compilerOptions": {
"deleteOutDir": true, // <- Si es true, primero eliminará el directorio de salida de la compilación.
"plugins": [
"@nestjs/swagger"
]
}
Más detalles aquí
Excelente Nico gracias por esos paso extra!
genial la documentaion!!!
Ahora la documentacion se genera mediante la ruta /api
si estan en 2022 y actualizaron su node y el swagger les presento problemas
hagan lo siguiente
yarn add @nestjs/platform-express @nestjs/common @nestjs/core @nestjs/axios
en el archivo app.module.ts
reemplazan
import { Module, HttpModule, HttpService } from '@nestjs/common';
import { Module } from '@nestjs/common';
import { HttpModule, HttpService } from '@nestjs/axios';
ya que en las nuevas versiones de @nestjs/common ya no soporta los modulos de HttpModule y HttpService .
por ende se instala Axios y queda ok.
😄
que buena esta clase
Swagger nest
Una consulta hice todo el proceso para ver los dto en swagger, pero el ultimo paso de rm-rf dist/ me sale rm no se reconoce como un comando interno o externo …Entonces no puedo ver los dto como se podria solucionar ya que voy en la mitad de la clase 14, la que sigue de esta pero sigo sin ver los dto. muchas Gracias
Si eres usuario windows y no lo sabes, para eliminar archivos en lugar de utilizar el comando ‘rm -rf’ utiliza ‘del’. En el ejemplo concreto de esta sesión sería:
del dist
Luego de esto escribe: YES o Y para aceptar.
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?