Request/Response DTOs & Mapping Pipelines
Master Request and Response DTO design, explicit entity mapping pipelines, and production CRUD API implementations.
Request/Response DTOs & Mapping Pipelines
To insulate the database persistence layer from public HTTP traffic, separate DTO classes must be constructed for incoming requests and outgoing responses.
1. Request DTO vs Response DTO Specifications
Request DTO (Client Input Contract)
Exposes ONLY the fields clients are permitted to supply during resource creation or update:
public class StudentRequestDto {
private String name;
private String email;
private Integer age;
// Getters and Setters (Notice: NO id, NO isDeleted, NO createdAt)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
}Response DTO (Client Output Contract)
Exposes ONLY public fields intended for client consumption:
public class StudentResponseDto {
private Long id;
private String name;
private String email;
private Integer age;
// Getters and Setters (Exposes generated id, hides internal audit fields)
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
}2. Explicit DTO Mapping Pipelines
Transformation between DTOs and Entities occurs at the Service Layer boundary:
Mapping Implementation in Service Layer
@Service
public class StudentService {
private final StudentRepository repository;
public StudentService(StudentRepository repository) {
this.repository = repository;
}
public StudentResponseDto createStudent(StudentRequestDto requestDto) {
// Step 1: Map Request DTO ──► Entity
Student student = mapToEntity(requestDto);
// Step 2: Persist Entity
Student savedStudent = repository.save(student);
// Step 3: Map Entity ──► Response DTO
return mapToResponseDto(savedStudent);
}
private Student mapToEntity(StudentRequestDto dto) {
Student student = new Student();
student.setName(dto.getName());
student.setEmail(dto.getEmail());
student.setAge(dto.getAge());
// Intentionally leaves id, isDeleted, createdAt to server control!
return student;
}
private StudentResponseDto mapToResponseDto(Student entity) {
StudentResponseDto dto = new StudentResponseDto();
dto.setId(entity.getId());
dto.setName(entity.getName());
dto.setEmail(entity.getEmail());
dto.getAge(entity.getAge());
return dto;
}
}3. CRUD API Implementation with DTOs
@RestController
@RequestMapping("/api/students")
public class StudentController {
private final StudentService service;
public StudentController(StudentService service) {
this.service = service;
}
@PostMapping
public StudentResponseDto createStudent(@Valid @RequestBody StudentRequestDto requestDto) {
return service.createStudent(requestDto);
}
@GetMapping("/{id}")
public StudentResponseDto getStudentById(@PathVariable Long id) {
return service.getStudentById(id);
}
@GetMapping
public List<StudentResponseDto> getAllStudents() {
return service.getAllStudents();
}
@PutMapping("/{id}")
public StudentResponseDto updateStudent(@PathVariable Long id, @Valid @RequestBody StudentRequestDto requestDto) {
return service.updateStudent(id, requestDto);
}
}❓ Knowledge Check
Where should DTO-to-Entity mapping take place in a layered Spring Boot application?
Why does updateStudent retrieve the existing Entity before applying DTO fields?
Entity Exposure Hazards & Security Gate Model
Master DTO architectural boundaries, the Building Security Gate mental model, mass assignment vulnerabilities, and data leakage prevention.
Bean Validation Annotations & @Valid Trigger
Master Spring Boot Bean Validation, constraint annotations (@NotBlank, @NotNull, @Email), the @Valid validation trigger, and skip-service rules.