📖 Scenario: You are building a simple Express server that manages user data. To keep your code clean and safe, you want to use the DTO (Data Transfer Object) pattern. This means you will create a special object that only sends the needed user information to the client, hiding sensitive details like passwords.
🎯 Goal: Build an Express route that sends user data using a DTO object. The DTO will include only the user's id, name, and email, excluding the password.
📋 What You'll Learn
Create a user object with id, name, email, and password
Create a UserDTO class that takes a user object and stores only id, name, and email
Create an Express route /user that returns the UserDTO as JSON
Use the DTO pattern to send only safe user data to the client
💡 Why This Matters
🌍 Real World
Using DTOs helps protect sensitive data when sending information from a server to a client, which is important in real web applications to keep user data safe.
💼 Career
Understanding and implementing the DTO pattern is a common task for backend developers working with APIs, especially in Node.js and Express environments.
Progress0 / 4 steps
1
Create the user data object
Create a constant called user with these exact properties and values: id set to 1, name set to "Alice", email set to "alice@example.com", and password set to "secret123".
Express
Hint
Use const user = { id: 1, name: "Alice", email: "alice@example.com", password: "secret123" }.
2
Create the UserDTO class
Create a class called UserDTO with a constructor that takes one parameter user. Inside the constructor, set this.id to user.id, this.name to user.name, and this.email to user.email. Do not include the password.
Express
Hint
Define class UserDTO with a constructor that copies only id, name, and email from the user.
3
Set up Express and create the /user route
Import Express by writing import express from 'express'. Create an Express app by calling express() and store it in a constant called app. Then create a GET route at /user that sends a new UserDTO created from the user object as JSON.
Express
Hint
Use import express from 'express', then const app = express(), and create a GET route with app.get('/user', (req, res) => { res.json(new UserDTO(user)) }).
4
Start the Express server
Add a line to start the Express server by calling app.listen on port 3000. Inside the listen callback, log the string "Server running on port 3000".
Express
Hint
Use app.listen(3000, () => { console.log("Server running on port 3000") }) to start the server.
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
Step 1: Understand the role of DTOs
DTOs are simple objects designed to carry data between parts of an application clearly and safely.
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.
Final Answer:
To clearly define and control the data sent between different parts of the app -> Option A
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
Step 1: Review class syntax for DTO
A DTO is often a simple class with a constructor to assign properties.
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'.
Final Answer:
class UserDTO { constructor(name, email) { this.name = name; this.email = email; } } -> Option D
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?
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
Step 1: Check how DTO instance is created
The code calls ProductDTO as a function without 'new', which is incorrect for classes.
Step 2: Understand class instantiation in JavaScript
Classes must be instantiated with 'new' keyword to create an object.
Final Answer:
Missing 'new' keyword when creating ProductDTO instance -> Option C
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
Step 1: Understand validation needs
The DTO must check that title and description are non-empty strings and throw errors if not.
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.
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
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 unknownstrongwhile earning +1 Grip toward your certificate.