Error Contracts, Anti-Patterns & Refactoring
Master structured validation error contracts, production anti-patterns, and refactoring entity-coupled CRUD APIs.
Error Contracts, Anti-Patterns & Refactoring
Returning clear, structured validation error responses when clients submit invalid inputs improves API usability and frontend integration.
1. Structured Validation Error Response Contracts
By default, Spring Boot returns a generic MethodArgumentNotValidException response. In production systems, a custom @RestControllerAdvice translates validation exceptions into a structured JSON error contract:
{
"success": false,
"message": "Validation failed for request payload",
"errors": {
"name": "Student name is mandatory and cannot be blank",
"email": "Student email must be a valid email format",
"age": "Student age must be at least 18"
}
}// Standard production error DTO structure
public class ValidationErrorResponseDto {
private boolean success = false;
private String message;
private Map<String, String> errors;
public ValidationErrorResponseDto(String message, Map<String, String> errors) {
this.message = message;
this.errors = errors;
}
public boolean isSuccess() { return success; }
public String getMessage() { return message; }
public Map<String, String> getErrors() { return errors; }
}2. Production Anti-Patterns Matrix
| Production Anti-Pattern | Operational Risk | Recommended Solution |
|---|---|---|
1. Direct @Entity Parameters | Mass assignment & sensitive data leakage | Use explicit StudentRequestDto & StudentResponseDto |
| 2. Single DTO for All Ops | Leaks unmodifiable fields during update operations | Create specific CreateStudentDto & UpdateStudentDto |
3. Missing @Valid Trigger | DTO constraint annotations are ignored completely | Add @Valid to @RequestBody parameters in Controllers |
| 4. Validation inside Service | Pollutes business logic with basic string checks | Enforce input constraints on DTOs via Bean Validation |
| 5. Returning HTTP 500 for Bad Input | Confuses client developers & misleads monitoring | Return HTTP 400 Bad Request for validation failures |
3. Production Design Checklist
Before marking a REST API implementation complete, verify:
- Request payloads use explicit Request DTOs (no Entities accepted at API boundary)
- Response payloads use explicit Response DTOs (no Entities returned to clients)
- DTO field validation uses appropriate constraints (
@NotBlank,@NotNull,@Min) - Controllers specify
@Valid @RequestBodyto trigger validation - Invalid requests return HTTP 400 Bad Request short-circuiting Service execution
- Service layer performs DTO ↔ Entity mapping explicitly
❓ Interactive Self-Assessment
Why should validation failures return HTTP 400 Bad Request instead of HTTP 500 Internal Server Error?
Refactoring an Entity-Coupled CRUD API
A legacy controller method accepts a raw @Entity Student directly and returns @Entity Student:
@PostMapping
public Student createStudent(@RequestBody Student student) {
return studentService.save(student);
}Refactor this endpoint using DTOs, explicit mapping, and Bean Validation constraints.
Bean Validation Annotations & @Valid Trigger
Master Spring Boot Bean Validation, constraint annotations (@NotBlank, @NotNull, @Email), the @Valid validation trigger, and skip-service rules.
HTTP Response Anatomy & ResponseEntity
Master HTTP response structure, status code taxonomy (200, 201, 204, 400, 404, 409, 500), decision matrices, and ResponseEntity construction.