Bird
Raised Fist0
Expressframework~5 mins

DTO pattern for data transfer in Express

Choose your learning style10 modes available
Introduction

The DTO pattern helps move data between parts of an app clearly and safely. It keeps data organized and easy to manage.

When sending user data from a client to a server in an API.
When you want to control exactly what data is sent or received.
When you need to validate or format data before using it.
When separating database models from what the app exposes.
When working with multiple layers like controllers and services.
Syntax
Express
class UserDTO {
  constructor({ id, name, email }) {
    this.id = id;
    this.name = name;
    this.email = email;
  }
}

// Usage example:
const dto = new UserDTO({ id: 1, name: 'Alice', email: 'alice@example.com' });

A DTO is usually a simple class or object that holds only the data you want to transfer.

It often has a constructor to set its properties from raw input.

Examples
This DTO holds product data with only id, title, and price fields.
Express
class ProductDTO {
  constructor({ id, title, price }) {
    this.id = id;
    this.title = title;
    this.price = price;
  }
}
This DTO is for creating a user and only includes name and email, ignoring other fields.
Express
class CreateUserDTO {
  constructor(data) {
    this.name = data.name;
    this.email = data.email;
  }
}
This DTO is for sending user data back to clients, hiding sensitive info like password.
Express
class UserResponseDTO {
  constructor(user) {
    this.id = user.id;
    this.name = user.name;
  }
}
Sample Program

This Express app uses a UserDTO class to accept user data in a POST request. It creates a DTO from the request body and sends it back as JSON. This keeps data structured and clear.

Express
import express from 'express';

class UserDTO {
  constructor({ id, name, email }) {
    this.id = id;
    this.name = name;
    this.email = email;
  }
}

const app = express();
app.use(express.json());

app.post('/users', (req, res) => {
  // Create DTO from request body
  const userDto = new UserDTO(req.body);

  // Here you could save userDto to database or process it

  // Send back the DTO as confirmation
  res.json(userDto);
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});
OutputSuccess
Important Notes

DTOs help keep your app's data clean and separate from database or UI details.

Always validate data before creating a DTO to avoid errors.

DTOs can make your code easier to test and maintain.

Summary

DTOs are simple objects to move data clearly between app parts.

They help control what data is sent or received.

Using DTOs improves code organization and safety.

Practice

(1/5)
1. What is the main purpose of using a DTO (Data Transfer Object) in an Express application?
easy
A. To clearly define and control the data sent between different parts of the app
B. To handle database connections directly
C. To style the user interface components
D. To manage server configuration settings

Solution

  1. Step 1: Understand the role of DTOs

    DTOs are simple objects designed to carry data between parts of an application clearly and safely.
  2. Step 2: Identify the correct purpose in Express context

    In Express, DTOs help control what data is sent or received, improving code clarity and security.
  3. Final Answer:

    To clearly define and control the data sent between different parts of the app -> Option A
  4. Quick Check:

    DTO purpose = data control and clarity [OK]
Hint: DTOs move data cleanly between app parts [OK]
Common Mistakes:
  • Confusing DTOs with database or UI code
  • Thinking DTOs handle server setup
  • Assuming DTOs manage styling
2. Which of the following is the correct way to define a simple DTO class in Express using JavaScript?
easy
A. function UserDTO(name, email) { return { name, email }; }
B. let UserDTO = (name, email) => { this.name = name; this.email = email; };
C. const UserDTO = { name: '', email: '' };
D. class UserDTO { constructor(name, email) { this.name = name; this.email = email; } }

Solution

  1. Step 1: Review class syntax for DTO

    A DTO is often a simple class with a constructor to assign properties.
  2. Step 2: Check each option's correctness

    class UserDTO { constructor(name, email) { this.name = name; this.email = email; } } correctly defines a class with a constructor assigning properties. function UserDTO(name, email) { return { name, email }; } returns an object but is a function, not a class. const UserDTO = { name: '', email: '' }; is a plain object, not a class. let UserDTO = (name, email) => { this.name = name; this.email = email; }; uses arrow function incorrectly with 'this'.
  3. Final Answer:

    class UserDTO { constructor(name, email) { this.name = name; this.email = email; } } -> Option D
  4. Quick Check:

    DTO class = constructor with properties [OK]
Hint: Use class with constructor for DTOs [OK]
Common Mistakes:
  • Using arrow functions with 'this' in DTOs
  • Defining DTO as plain object without constructor
  • Returning object from function instead of class
3. Given this DTO and Express route, what will be the JSON response when sending {"name":"Alice","email":"alice@example.com","password":"secret"} in the request body?
class UserDTO {
  constructor(name, email) {
    this.name = name;
    this.email = email;
  }
}

app.post('/user', (req, res) => {
  const userDto = new UserDTO(req.body.name, req.body.email);
  res.json(userDto);
});
medium
A. {"name":"Alice","email":"alice@example.com","password":"secret"}
B. {"name":"Alice","email":"alice@example.com"}
C. {"password":"secret"}
D. {}

Solution

  1. Step 1: Understand DTO construction

    The UserDTO constructor only assigns name and email properties, ignoring password.
  2. Step 2: Analyze response JSON

    The response sends the userDto object, which includes only name and email fields.
  3. Final Answer:

    {"name":"Alice","email":"alice@example.com"} -> Option B
  4. Quick Check:

    DTO filters out extra fields [OK]
Hint: DTO only includes defined properties [OK]
Common Mistakes:
  • Expecting password to be included in response
  • Confusing request body with DTO properties
  • Assuming all request fields are sent back
4. Identify the error in this DTO usage in an Express route:
class ProductDTO {
  constructor(id, name) {
    this.id = id;
    this.name = name;
  }
}

app.post('/product', (req, res) => {
  const productDto = ProductDTO(req.body.id, req.body.name);
  res.json(productDto);
});
medium
A. Response should use res.send instead of res.json
B. Incorrect property names in constructor
C. Missing 'new' keyword when creating ProductDTO instance
D. DTO class should be a function, not a class

Solution

  1. Step 1: Check how DTO instance is created

    The code calls ProductDTO as a function without 'new', which is incorrect for classes.
  2. Step 2: Understand class instantiation in JavaScript

    Classes must be instantiated with 'new' keyword to create an object.
  3. Final Answer:

    Missing 'new' keyword when creating ProductDTO instance -> Option C
  4. Quick Check:

    Class instantiation requires 'new' [OK]
Hint: Always use 'new' with class constructors [OK]
Common Mistakes:
  • Calling class like a regular function
  • Confusing res.send and res.json usage
  • Thinking DTO must be a function, not class
5. You want to create a DTO that only accepts non-empty strings for title and description in an Express app. Which approach correctly enforces this validation inside the DTO class?
hard
A. class TaskDTO { constructor(title, description) { if (!title || typeof title !== 'string') throw new Error('Invalid title'); if (!description || typeof description !== 'string') throw new Error('Invalid description'); this.title = title; this.description = description; } }
B. class TaskDTO { constructor(title, description) { this.title = title || 'default'; this.description = description || 'default'; } }
C. class TaskDTO { constructor(title, description) { this.title = title; this.description = description; } }
D. function createTaskDTO(title, description) { return { title, description }; }

Solution

  1. Step 1: Understand validation needs

    The DTO must check that title and description are non-empty strings and throw errors if not.
  2. Step 2: Evaluate each option's validation

    class TaskDTO { constructor(title, description) { if (!title || typeof title !== 'string') throw new Error('Invalid title'); if (!description || typeof description !== 'string') throw new Error('Invalid description'); this.title = title; this.description = description; } } explicitly checks and throws errors for invalid inputs. class TaskDTO { constructor(title, description) { this.title = title || 'default'; this.description = description || 'default'; } } assigns defaults instead of validating. class TaskDTO { constructor(title, description) { this.title = title; this.description = description; } } assigns without checks. function createTaskDTO(title, description) { return { title, description }; } is a function without validation.
  3. Final Answer:

    class TaskDTO { constructor(title, description) { if (!title || typeof title !== 'string') throw new Error('Invalid title'); if (!description || typeof description !== 'string') throw new Error('Invalid description'); this.title = title; this.description = description; } } -> Option A
  4. Quick Check:

    Validation inside constructor = class TaskDTO { constructor(title, description) { if (!title || typeof title !== 'string') throw new Error('Invalid title'); if (!description || typeof description !== 'string') throw new Error('Invalid description'); this.title = title; this.description = description; } } [OK]
Hint: Validate inputs inside constructor, throw errors if invalid [OK]
Common Mistakes:
  • Skipping validation and assigning defaults silently
  • Using functions without validation for DTOs
  • Not throwing errors on invalid data
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard