Pular para o conteúdo

Como Lidar com DTOs no Framework Nest.js

O Nest.js é um dos frameworks de desenvolvimento back-end mais populares para Node.js, conhecido por sua escalabilidade, modularidade e facilidade de uso. Ao desenvolver aplicativos com Nest.js, é comum lidar com DTOs (Data Transfer Objects) para transferir dados entre as camadas da aplicação.

Neste artigo, exploraremos o que são DTOs, por que são importantes e como lidar com eles no contexto do Nest.js.

Introdução aos DTOs

DTOs, ou Data Transfer Objects, são objetos que transportam dados entre diferentes partes de uma aplicação. Eles servem como uma camada de abstração que permite a transferência de dados de forma estruturada e segura. Os DTOs são particularmente úteis em aplicativos Nest.js, onde a modularidade e a organização do código são essenciais.

Por que usar DTOs no Nest.js? Aqui estão algumas razões:

1. Separação de preocupações

Usar DTOs ajuda a separar as preocupações relacionadas à validação e manipulação de dados das camadas de controle e serviço. Isso torna o código mais organizado e fácil de manter.

2. Validação de entrada

DTOs permitem que você defina regras de validação de dados em um local centralizado. Isso garante que os dados de entrada sejam sempre válidos antes de serem processados pela aplicação.

3. Documentação clara

DTOs tornam a API de sua aplicação mais clara e autoexplicativa. Ao definir DTOs para as solicitações e respostas da API, os desenvolvedores que usam sua API terão uma compreensão mais fácil dos dados necessários e das respostas esperadas.

Criando DTOs no Nest.js

Agora que entendemos por que os DTOs são úteis, vamos dar uma olhada em como criá-los no Nest.js. Para criar um DTO, você precisa definir uma classe TypeScript simples com propriedades que representam os dados que você deseja transferir. Aqui está um exemplo:

// user.dto.ts
export class CreateUserDto {
  readonly username: string;
  readonly email: string;
  readonly password: string;
}

Neste exemplo, criamos um DTO chamado CreateUserDto com três propriedades: username, email e password. Essas propriedades representam os dados que precisamos para criar um novo usuário em nossa aplicação.

Usando DTOs em Controladores

Agora que temos nosso DTO definido, podemos usá-lo em um controlador Nest.js. Suponhamos que estamos criando uma rota para criar um novo usuário. Aqui está como o controlador pode usar o DTO:

// user.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { CreateUserDto } from './user.dto';

@Controller('users')
export class UserController {
  @Post()
  async createUser(@Body() createUserDto: CreateUserDto) {
    // Aqui, createUserDto contém os dados enviados na solicitação
    // Faça a lógica para criar um novo usuário
  }
}

Neste exemplo, usamos a anotação @Body() para dizer ao Nest.js que esperamos que os dados da solicitação POST sejam desserializados em um objeto createUserDto do tipo CreateUserDto. Isso permite que a lógica do controlador acesse facilmente os dados necessários para criar um novo usuário.

Validando DTOs

Uma das grandes vantagens de usar DTOs é a capacidade de validar os dados de entrada de forma eficaz. O Nest.js fornece uma maneira fácil de fazer isso usando bibliotecas de validação como o class-validator. Primeiro, você precisa instalar o pacote:

npm install class-validator class-transformer

Agora, você pode usar a validação em seu DTO. Modificaremos nosso CreateUserDto para incluir algumas validações:

import { IsString, IsEmail, MinLength } from 'class-validator';

export class CreateUserDto {
  @IsString()
  readonly username: string;

  @IsEmail()
  readonly email: string;

  @IsString()
  @MinLength(8)
  readonly password: string;
}

Neste exemplo, adicionamos algumas anotações de validação às propriedades do DTO. O @IsString() garante que username e password sejam strings, enquanto @IsEmail() garante que email seja um formato de e-mail válido. Além disso, usamos @MinLength(8) para garantir que a senha tenha pelo menos 8 caracteres.

Lidando com Erros de Validação

Ao usar DTOs com validação, é importante lidar adequadamente com erros de validação. Você pode fazer isso criando um filtro de exceção personalizado que captura erros de validação e os converte em respostas HTTP apropriadas.

// validation.filter.ts
import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';
import { ValidationError } from 'class-validator';
import { Response } from 'express';

@Catch(ValidationError)
export class ValidationFilter implements ExceptionFilter {
  catch(exception: ValidationError, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();

    const errors = exception
      .map((error) => Object.values(error.constraints))
      .flat();

    response.status(400).json({ message: 'Erro de validação', errors });
  }
}

Neste exemplo, criamos um filtro de exceção ValidationFilter que pega erros de validação e os converte em uma resposta JSON com um código de status 400 (Bad Request).

Registrando o Filtro de Validação

Para usar o filtro de validação, você precisa registrá-lo em seu módulo principal:

// app.module.ts
import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { ValidationFilter } from './validation.filter';

@Module({
  // ...
  providers: [
    {
      provide: APP_FILTER,
      useClass: ValidationFilter,
    },
  ],
})
export class AppModule {}

Agora, o filtro de validação será aplicado automaticamente a todos os controladores que usam DTOs com anotações de validação.

Conclusão

Neste artigo, exploramos o uso de DTOs no Framework Nest.js. Aprendemos por que os DTOs são importantes para separar preocupações, validar entrada de dados e melhorar a documentação da API. Vimos como criar e usar DTOs em controladores, bem como como adicionar validações aos DTOs usando o class-validator. Além disso, discutimos como lidar com erros de validação usando um filtro de exceção personalizado.

O uso de DTOs no Nest.js pode melhorar significativamente a organização e a clareza do código, tornando-o mais fácil de manter e escalar. À medida que você continua a desenvolver aplicativos com o Nest.js, considere o uso de DTOs sempre que necessário para transferir dados de forma eficiente e segura.

Espero que este artigo tenha sido útil para você. Se você tiver alguma dúvida ou comentário, não hesite em compartilhá-los abaixo. Como você lida com DTOs em seus aplicativos Nest.js? Quais são suas melhores práticas? Compartilhe suas experiências e insights!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.