No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Integrando Swagger y PartialType con Open API

13/17
Recursos

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.

C贸mo hacer la documentaci贸n API Rest

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.

Tipado de la documentaci贸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.

Documentaci贸n Swagger.png

De esta manera, observar谩s en la documentaci贸n que indica el tipo de dato que requiere cada uno de tus endpoints.

Cuadro de c贸digo para uso de swagger

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 28

Preguntas 18

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

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 鈥楽wagger 5鈥, as铆 que esto es una alternativa.

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 salia este error
Error: Cannot find module 鈥楡nestjs/core/router/route-path-factory鈥

la solucion esta aqui https://github.com/nestjs/swagger/issues/1433

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.

Si como yo estan usando Fastify, necesitan instalar:

npm install --save @nestjs/swagger fastify-swagger

yarn:

yarn add @nestjs/swagger fastify-swagger

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

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:


https://github.com/nestjs/swagger/issues/1868

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

  1. Instalamos las dependencias npm install --save @nestjs/swagger swagger-ui-express
  2. Editamos el archivo nest-cli.js
{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
}
  1. En el main.ts se agrega la configuracion de swagger antes de listen del server
const config = new DocumentBuilder()
    .setTitle('API')
    .setDescription('Store')
    .setVersion('1.0')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('docs', app, document);
  1. En los DTOs tenemos que importar el partialtype de swagger para que tome los cambios
import { PartialType } from '@nestjs/swagger';
  1. Borramos la carpeta dist rm -rf dist o click derecho borrar carpeta

  2. Ejecutamos la aplicacion npm run start:dev

PickType

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!!!

Creo que ya me gust贸 m谩s Nest que Express鈥 Solo por esto

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 鈥ntonces 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 鈥榬m -rf鈥 utiliza 鈥榙el鈥. En el ejemplo concreto de esta sesi贸n ser铆a:

del dist

Luego de esto escribe: YES o Y para aceptar.