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
- 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
- We also need to install
reflect-metadata
as it is a prerequisite ofclass-transformer
library.
npm install reflect-metadata
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;
}
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);
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...
});
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);
});
Here the response will be like this:
{
firstName: "Mostafizur",
lastName: "Rahman",
email: "mostafizur@example.com",
age: "27",
fullName: "Mostafizur Rahman"
}
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);
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)
EXACTLY what I was looking for! Excellent write-up