Logo

dev-resources.site

for different kinds of informations.

Understanding DTOs (Data Transfer Objects) in NestJSπŸš€

Published at
1/6/2025
Categories
typescript
programming
beginners
nestjs
Author
abhivyaktii
Author
11 person written this
abhivyaktii
open
Understanding DTOs (Data Transfer Objects) in NestJSπŸš€

In modern web application development, ensuring that the data passed between the client and server is structured, validated, and secure is paramount. One of the tools that help achieve this is the DTO (Data Transfer Object) design pattern. In NestJS, DTOs are frequently used to define the structure of request and response bodies, while also integrating data validation to ensure that the data meets specific requirements.

In this blog post, we will explore what DTOs are, how to create and use them in NestJS, and how they help manage the flow of data in your application.


What is a DTO (Data Transfer Object)? πŸ€”

A Data Transfer Object (DTO) is a design pattern that is used to transfer data between different layers of an application. Typically, DTOs are used to encapsulate data that is sent over a network, whether it's in an API request or response. DTOs are especially helpful in:

  • Defining the structure of the data πŸ“Š
  • Performing data validation to ensure data integrity βœ…
  • Preventing issues like over-fetching or under-fetching of data πŸ”’

In NestJS, DTOs are usually classes with decorators that define the structure and validation rules for the data. They ensure that the incoming and outgoing data is well-formed, validated, and serialized properly.


Creating a Simple DTO in NestJS ✨

In NestJS, you create a DTO by defining a class. You can then use decorators provided by libraries like class-validator and class-transformer to define validation rules and transform the data.

Example 1: Simple DTO for User Registration πŸ‘€

Let’s say you are building a user registration API and need a DTO to validate the data the user sends.

import { IsString, IsEmail, IsInt, Min, Max } from 'class-validator';

export class CreateUserDto {
  @IsString()
  name: string;

  @IsEmail()
  email: string;

  @IsInt()
  @Min(18)
  @Max(120)
  age: number;
}
Enter fullscreen mode Exit fullscreen mode

In this DTO:

  • The @IsString() decorator ensures that the name property is a string. ✍️
  • The @IsEmail() decorator ensures that the email property is a valid email address πŸ“§.
  • The @IsInt(), @Min(18), and @Max(120) decorators validate that the age is an integer between 18 and 120 πŸ§‘β€πŸ€β€πŸ§‘.

Enabling Validation with the Validation Pipe πŸ’ͺ

NestJS integrates the class-validator library for validation and class-transformer for transforming data. To use validation, you need to enable the ValidationPipe globally in your app.

In the main.ts file, add the following code to activate the global validation pipe:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Enable global validation
  app.useGlobalPipes(new ValidationPipe());

  await app.listen(3000);
}
bootstrap();
Enter fullscreen mode Exit fullscreen mode

This will ensure that every incoming request is validated according to the rules defined in your DTOs. 🎯


Using DTOs in Controllers πŸ§‘β€πŸ’»

Once the DTO is created and validation is enabled, you can use it in your controllers. For example, you might have a POST endpoint to register a new user, which would accept a CreateUserDto.

Example 2: Controller Using DTO πŸš€

import { Controller, Post, Body } from '@nestjs/common';
import { CreateUserDto } from './create-user.dto';
import { UsersService } from './users.service';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  async create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }
}
Enter fullscreen mode Exit fullscreen mode

In the above example:

  • The @Body() decorator extracts the body of the incoming request and automatically maps it to the CreateUserDto. πŸ“₯
  • The ValidationPipe ensures that any invalid data will result in a 400 HTTP error response ⚠️.

Using DTOs for Responses πŸ”„

DTOs are not only useful for request validation but also for shaping the data that your application returns in response to the client. This helps prevent exposing unnecessary or sensitive data and ensures that the response format remains consistent.

Example 3: Response DTO for User Data πŸ“¨

export class UserResponseDto {
  id: number;
  name: string;
  email: string;
}
Enter fullscreen mode Exit fullscreen mode

In your controller, you can use this response DTO to return a user object:

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  async create(@Body() createUserDto: CreateUserDto) {
    const newUser = await this.usersService.create(createUserDto);

    // Return a response with the UserResponseDto
    return new UserResponseDto(newUser);
  }
}
Enter fullscreen mode Exit fullscreen mode

In this case, the UserResponseDto ensures that only the id, name, and email properties are included in the response, excluding any other internal data (like passwords). πŸ”


Partial DTOs for Updates πŸ”„

When dealing with updates (such as with a PATCH request), not all fields are required to be provided. NestJS allows you to define optional fields in your DTOs using the @IsOptional() decorator.

Example 4: DTO for Updating a User ✍️

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

export class UpdateUserDto {
  @IsOptional()
  @IsString()
  name?: string;

  @IsOptional()
  @IsEmail()
  email?: string;
}
Enter fullscreen mode Exit fullscreen mode

In this UpdateUserDto:

  • The @IsOptional() decorator allows fields to be omitted from the request body. If the client does not provide a name or email, they won’t trigger validation errors. βœ…

Nesting DTOs πŸ”—

DTOs can be nested when you have complex data structures. For example, a user might have an address, which is itself a DTO.

Example 5: Nesting DTOs for User and Address 🏑

export class AddressDto {
  @IsString()
  street: string;

  @IsString()
  city: string;

  @IsString()
  postalCode: string;
}

export class CreateUserDto {
  @IsString()
  name: string;

  @IsEmail()
  email: string;

  @IsInt()
  age: number;

  @IsOptional()
  @Type(() => AddressDto)  // Use the Type decorator for nested objects
  address?: AddressDto;
}
Enter fullscreen mode Exit fullscreen mode

Here, the CreateUserDto includes an AddressDto. The @Type() decorator (from class-transformer) is used to ensure that the nested AddressDto is properly transformed and validated. πŸ› οΈ


Conclusion πŸŽ‰

DTOs in NestJS are a powerful tool to help ensure that the data flowing through your application is structured, validated, and secure. They provide several benefits:

  • Data Validation: Ensures incoming data meets the required format and constraints. βœ…
  • Consistency: Standardizes how data is structured, both for requests and responses. πŸ“
  • Security: Helps prevent issues like over-fetching of sensitive data. πŸ”

By using DTOs, you ensure that your NestJS applications are scalable, secure, and maintainable. Whether you're validating user input or shaping API responses, DTOs play an essential role in modern NestJS development. πŸš€

nestjs Article's
30 articles in total
Favicon
Understanding CORS and Setting it up with NestJS + Fastify πŸš€
Favicon
Crudify: Automate Your Mongoose CRUD Operations in NestJS
Favicon
Building "Where Am I?": A GeoGuessr Alternative for Mobile
Favicon
Utilizando la librerΓ­a Mongoose
Favicon
How to easily send emails in NestJS?
Favicon
Why NestJS Is The New Gold Standard For Node Backend Development
Favicon
Designing RBAC Permission System with Nest.js: A Step-by-Step Guide
Favicon
How to work with CAR files with NestJS
Favicon
Handle Payments Module in NestJS
Favicon
What we're working on: Database Entities
Favicon
Deploy NestJS and NextJS application in same server using pm2 and Nginx
Favicon
Advance nest.js
Favicon
Converting date by user time zone in "NestJS", and entering and displaying date in "Angular"
Favicon
Web Performance Optimization Tips from My Latest Project
Favicon
Blogsphere | A blogging website made with MERN stack. includes user management.
Favicon
nest.js
Favicon
[Boost]
Favicon
Wanna test NestJS out - any tips
Favicon
nestJS Modern Framework for Scalable Applications
Favicon
πŸš€ Applying SOLID Principles in NestJS: A Practical Guide
Favicon
Nestjs
Favicon
Which One Should You Choose NEST JS or EXPRESSΒ JS?
Favicon
Integrating and storing the selected user language into the database in a full-stack application on "Angular" and "NestJS"
Favicon
Hello,help review my fullstack website stack : nestjs,mongodb and reactjs. https://events-org-siiv.vercel.app/
Favicon
The Ultimate Tech Stack for Startups in 2025
Favicon
NestJS and more
Favicon
Como implementar Feature Flags em seu Backend NestJS
Favicon
Building an Image Moderation System with AWS Rekognition, Nest.js, and React
Favicon
How to Create a quick Authentication library for NestJS/MongoDB application
Favicon
Understanding DTOs (Data Transfer Objects) in NestJSπŸš€

Featured ones: