DTOs vs Entities
Never expose your database structure directly to the client.
The Restaurant Menu vs Kitchen Inventory Analogy:
Imagine you walk into a restaurant.
- Entity (Kitchen Inventory): Inside the kitchen, there is raw material — 10kg of potatoes, 5kg of onions, expired milk. If you show the customer the entire kitchen inventory, they will get confused and leave. Some things are secret (like cost price).
- DTO (Menu Card): You hand the customer a printed Menu Card. It only contains what they need to see — Dish name and price.
In Spring Boot, Book is your Entity (what is saved in the database). But you should send a BookDTO to the user via the API, hiding sensitive or unwanted data.
- Security: Imagine a
Userentity haspasswordandsalaryfields. If you return the Entity, the API exposes passwords! A DTO hides them. - Decoupling: Database structure changes (e.g., renaming a column) shouldn't break the Angular frontend. A DTO creates a stable API contract.
- Customization: Sometimes an API needs to combine data from two tables (User + Address). A DTO can hold this combined data easily.
package com.devinhyderabad;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@RestController
@RequestMapping("/api/users")
class UserController {
// 1. Imagine this is fetched from a Database
private UserEntity getUserFromDb(int id) {
// In a real app, this would have password, salary, internal flags, etc.
return new UserEntity(id, "Deva", "secretPassword123", 50000, "ADMIN");
}
// 2. The API endpoint returns a DTO, NOT the Entity
@GetMapping("/{id}")
public ResponseEntity getUser(@PathVariable int id) {
UserEntity entity = getUserFromDb(id); // Fetch raw data
if (entity == null) return ResponseEntity.notFound().build();
// 3. Map Entity to DTO manually (We will learn ModelMapper in Phase 5)
UserResponseDTO dto = new UserResponseDTO();
dto.setId(entity.getId());
dto.setName(entity.getName());
dto.setRole(entity.getRole());
// Notice: We completely ignored 'password' and 'salary'!
return ResponseEntity.ok(dto);
}
}
// --- ENTITY (Database Model) ---
class UserEntity {
private int id;
private String name;
private String password; // SENSITIVE
private int salary; // SENSITIVE
private String role;
public UserEntity(int id, String name, String password, int salary, String role) {
this.id = id; this.name = name; this.password = password;
this.salary = salary; this.role = role;
}
public int getId() { return id; }
public String getName() { return name; }
public String getPassword() { return password; }
public int getSalary() { return salary; }
public String getRole() { return role; }
}
// --- DTO (API Response Model) ---
class UserResponseDTO {
private int id;
private String name;
private String role;
// No password, no salary!
public void setId(int id) { this.id = id; }
public void setName(String name) { this.name = name; }
public void setRole(String role) { this.role = role; }
public int getId() { return id; }
public String getName() { return name; }
public String getRole() { return role; }
} If you call this API, the JSON output will only be: {"id":1,"name":"Deva","role":"ADMIN"}. The password and salary are perfectly hidden.
Interview Question: "What is a DTO and why do we use it instead of JPA Entities in REST APIs?"
Answer: A Data Transfer Object (DTO) is a plain Java object used to carry data between processes. We use DTOs to decouple the database structure from the API response. This prevents sensitive data (like passwords) from leaking, avoids lazy-loading exceptions (like LazyInitializationException) during JSON serialization, and allows us to combine multiple entities into a single response shape.
Enterprise Note: Mapping Entity to DTO manually (like in the code above) is tedious for large objects. In Phase 5, we will use a library called MapStruct (or ModelMapper) that automatically copies data from Entity to DTO using just an interface, saving hundreds of lines of boilerplate code.
Key Takeaways
- ✅ DTO = Data Transfer Object — decouples DB model from API response
- ✅ DTOs prevent sensitive data (passwords, salary) from leaking
- ✅ DTOs create a stable API contract independent of DB schema
- ✅ MapStruct or ModelMapper can automate Entity-to-DTO mapping
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login