Data Transfer Objects (DTO) Pattern in Programming
→ DTOs are a common concept in Software Development eg. Nest.js framework of Node.js, Java Spring Boot, etc.
A Data transfer object (DTO) is an object that carries data between processes — Wikipedia
A DTO is an object that defines how the data will be sent over the network — Nest.js
What is DTO?
→ DTO are class or interface that has specific data keys in it.
→ We make incoming Data from Request or Network to be of the same type.
Eg.
export class CreateTaskDto {
title: string;
description: string;
}
Eg 2:
export class GetTasksFilterDto {
status?: TaskStatus;
search?: string;
}
Why use DTO?
→ Suppose we have a data object with specific keys in it used in controllers, then the same passed in the service.
→ As your application grows it will used repeatedly in many places.
→ So the standard is to create a DTO Class and Typescript or Java will be of type DTO
Reason 1: Not repeated in multiple code files
→ In future, if more keys are added or object keys are modified changing in one place will be easier instead of doing it in multiple places in files.
Reason 2: Single Source of Truth in one file
Practical Demo 1:
→ Let us observe DTO implemented in the Nest JS Project.
Note: It can be done in Java, Python, and other programming languages and is a standard.
→ If are writing simple REST APIs. How can we implement there?
STEP 1: Create a dto directory inside the task module →create-task.dto.ts
Path: src/tasks/dto/create-task.dto.ts
export class CreateTaskDto {
title: string;
description: string;
}
NOTE: Every module has its DTO.
Controller:
Path: src/tasks/tasks.controller.ts
import { CreateTaskDto } from './dto/create-task.dto';
@Post()
createTask(@Body() createTaskDto: CreateTaskDto): Task {
return this.taskService.createTask(createTaskDto);
}
→ Now like regular Typescript we have defined the incoming data must-have of this DTO
→ Finally in services — we can extract data coming from the Body of the postman.
Services:
Path: src/tasks/tasks.service.ts
createTask(createTaskDto) {
const { title, description } = createTaskDto; // Extracted data
const task: Task = {
id: uuid(),
title,
description,
status: TaskStatus.OPEN
}
this.tasks.push(task);
return task;
}
→ With this shape our data is decided and can be changed from DTO only — single place
Practical Demo 2:
→ We are fetching All Tasks a REST endpoint. The idea is if some filter query parameter is passed — it must follow filterDTO type data only
Path: src/tasks/dto/get-tasks.dto.ts
import { TaskStatus } from "../task.model";
export class GetTasksFilterDto {
status?: TaskStatus;
search?: string;
}
→ Now the idea is simple if Get All Task where data is received we will pass as type as this DTO
import { GetTasksFilterDto } from './dto/get-tasks.dto';
@Get()
getTasks(@Query() filterDto: GetTasksFilterDto): Task[] {
if(Object.keys(filterDto)) {
return this.taskService.getTasksWithFilter(filterDto);
} else {
return this.taskService.getAllTasks();
}
}
→ Now once the type is checked regular data flows to the service.
→ So once type checking passes job of DTO is done. It is good for data validation.
→ Let us see the service. The below code is just logic for this REST API and not DTO:
getTasksWithFilter(filterDto: GetTasksFilterDto) : Task[] {
const { status, search } = filterDto;
let tasks = this.getAllTasks();
if(status) {
tasks = tasks.filter(task => task.status === status);
}
if(search) {
tasks = tasks.filter(task => {
return task.title.includes(search) || task.description.includes(search);
});
}
return tasks;
}
Video:
Conclusion:
Data Transfer Object (DTO) is a standard use in project applications where specific data shape is required. It is used in most programming languages.
The idea is to keep data structure in a single source of truth. If tomorrow new requirements come to add a few more fields we can add them in the DTO file itself.
Finally, DTO can written using a class or interface. Class is preferred mostly as it has more capabilities.
Thank you for reading till the end 🙌 . If you enjoyed this article or learned something new, support me by clicking the share button below to reach more people and/or subscribe Happy Learnings !! to see some other tips, articles, and things I learn about and share there.