DEV Community

Cover image for Simplifying DTO Management In Express.js with Class-Transformer
Md Mostafizur Rahman
Md Mostafizur Rahman

Posted on

Simplifying DTO Management In Express.js with Class-Transformer

Data Transfer Objects (DTOs) are an essential concept in modern software development. They are used to transfer data between different layers of an application or between different applications. A DTO is a simple object that carries data between different layers of an application, such as between a client and a server. DTOs are often used to reduce the amount of data sent between the client and server and to provide a clear separation of concerns.

To make the process of managing DTOs easier, we can use the class-transformer library. Class-transformer is a TypeScript library that helps to convert plain JavaScript objects to class instances and vice versa. In this article, we will explore how to use class-transformer in Express.js to manage DTOs.

Installing Class-transformer

  1. To get started, we need to install the class-transformer library. Open a terminal window and navigate to your project directory. Then run the following command:
npm install class-transformer
Enter fullscreen mode Exit fullscreen mode
  1. We also need to install reflect-metadata as it is a prerequisite of class-transformer library.
 npm install reflect-metadata
Enter fullscreen mode Exit fullscreen mode

Creating a DTO Class

The first step in using class-transformer is to create a DTO class. A DTO class is a TypeScript class that represents the data we want to transfer between different layers of our application.

Here's an example of a simple DTO class that represents a user:

import { Expose } from 'class-transformer';

export class UserDTO {
  @Expose()
  firstName!: string;

  @Expose()
  lastName!: string;

  @Expose()
  email!: string;

  @Expose()
  age!: number;

  @Exclude()
  password!: string;
}
Enter fullscreen mode Exit fullscreen mode

In the example above, we've defined a DTO class called UserDTO that has five properties: firstName, lastName, email, age and password. We've also used the Expose decorator from class-transformer to specify that each property should be included and Exclude decorator to specify that the property should not be included when we convert an instance of this class to a plain JavaScript object.

Converting an Object to a DTO

To convert an object to a DTO, we can simply create an instance of the DTO class and pass in the object as a parameter. Class-transformer will automatically map the object's properties to the corresponding properties in the DTO class.

Here's an example of how to convert an object to a UserDTO:

import { plainToClass } from 'class-transformer';
import { UserDTO } from './user.dto';

const user = {
  firstName: 'John',
  lastName: 'Doe',
  email: 'johndoe@example.com',
  age: 30,
  password: "secretpass", 
  confirmPassword: "secretpass"
};

const userDTO = plainToClass(UserDTO, user, { excludeExtraneousValues: true });
console.log(userDTO);
Enter fullscreen mode Exit fullscreen mode

In the example above, we've created an object called user that represents a user. We've then used the plainToClass function from class-transformer to convert the user object to a UserDTO instance. Finally, we've logged the UserDTO instance to the console.

Converting request bodies

One of the most common use cases for class-transformer is converting request bodies. When we receive data from an API client, it usually comes in the form of a JSON object. We can use class-transformer to convert this JSON object to an instance of our DTO class.

import { plainToClass } from 'class-transformer';
import { Request, Response } from 'express';
import { UserDTO } from './dto/user.dto';

app.post('/users', async (req: Request, res: Response) => {
  const userDTO = plainToClass(UserDTO, req.body. { excludeExtraneousValues: true });

  // Create user in database...
});
Enter fullscreen mode Exit fullscreen mode

Converting API responses

We can also useclass-transformer to convert API responses and provide the specific shape of data which the API client needs. Here is an example of how we can do this:

export class UserResponseDTO{
  @Expose()
  firstName!: string;

  @Expose()
  lastName!: string;

  @Expose()
  email!: string;

  @Expose()
  age!: number;

  @Expose({ name: 'fullName' })
  getFullName() {
    return this.firstName + ' ' + this.lastName;
  }
}

app.get('/users/:id', async (req, res) => {
  const id = req.params.id;
  const user = UserModel.findById(id); // full user object
    const userResponseDTO = plainToClass(UserDTO, req.body. { excludeExtraneousValues: true });
  res.json(userResponseDTO);
});
Enter fullscreen mode Exit fullscreen mode

Here the response will be like this:

{
 firstName: "Mostafizur",
 lastName: "Rahman",
 email: "mostafizur@example.com",
 age: "27",
 fullName: "Mostafizur Rahman"
}
Enter fullscreen mode Exit fullscreen mode

Converting a DTO to an Object

To convert a DTO to an object, we can use classToPlain function from class-transformer to convert the a UserDTO instance to a user object. Class-transformer will automatically convert the DTO instance to a plain JavaScript object.

Here's an example of how to convert a UserDTO instance to an object:

import { classToPlain } from 'class-transformer';
import { UserDTO } from './user.dto';

const userDTO = new UserDTO();
userDTO.firstName = 'John';
userDTO.lastName = 'Doe';
userDTO.email = 'johndoe@example.com';
userDTO.age = 30;

const user = classToPlain(userDTO);
console.log(user);
Enter fullscreen mode Exit fullscreen mode

In the example above, we've created a UserDTO instance called userDTO. We've then set the values of its properties. Finally, we've logged the plain user object to the console.

Conclusion

Class-transformer is a powerful tool for managing data transfer objects. In this article I have shown an high level overview of the class-transformer library. To learn more about this library please checkout out their official documentation here.

Top comments (1)

Collapse
 
herringtown profile image
Greg Herrington

EXACTLY what I was looking for! Excellent write-up