Concept
API hardening is the discipline that keeps tutorial code from leaking into production habits. DTOs, ProblemDetail, mapper decisions, and API docs are boring in the best possible way.
Task
- Add Bean Validation to request DTOs.
- Return RFC 9457 ProblemDetail for tested error paths.
- Enforce the controller/entity boundary with an ArchUnit rule.
- Pin springdoc exactly and keep a Swagger proof artifact.
- Write ADR-002 for manual mapping.
Run
./gradlew test --tests "*ApiBoundaryArchTest"./gradlew test --tests "*ProblemDetailContractTest"Expected Result
- CI fails if a controller depends on persistence entities.
- Error responses have type, title, status, and detail fields.
Common Traps
- Returning entities because the first endpoint is small.
- Using a global response envelope when pagination metadata is enough.
- Documenting Swagger without pinning the dependency that renders it.
Hint Ladder
Hint 1
Manual mapping is fine while the course is still teaching the boundary.
Hint 2
ProblemDetail should be tested through HTTP, not only instantiated in a unit test.
Hint 3
The API docs artifact is proof that the contract renders, not a design substitute.
Solution
See ApiExceptionHandler.java, ApiBoundaryArchTest.java, and ADR-002.