Data Transfer Objects (DTO) Pattern in Programming

Amir Mustafa
4 min readDec 9, 2023

→ 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.

--

--

Amir Mustafa

JavaScript Specialist | Consultant | YouTuber 🎬. | AWS ☁️ | Docker 🐳 | Digital Nomad | Human. Connect with me on https://www.linkedin.com/in/amirmustafa1/