A REST API’s request and response structures are part of its public contract. If validation is inconsistent or error responses change between endpoints, clients become more complicated and integration becomes harder to maintain.
Spring Boot supports request validation and centralized exception handling, making it possible to create predictable API behavior.
Define request validation rules
Bean Validation annotations express constraints directly on request models:
public record CreateProductRequest(
@NotBlank
@Size(max = 120)
String name,
@Positive
BigDecimal price
) {}
The example uses BigDecimal for monetary values and requires a positive price. Applications should also define currency and rounding policies where necessary.
Make sure the appropriate validation dependency is included in the project.
Activate validation in controllers
A controller can use @Valid to validate the incoming request:
@PostMapping("/products")
public ResponseEntity<ProductResponse> create(
@Valid @RequestBody CreateProductRequest request) {
ProductResponse created = productService.create(request);
return ResponseEntity
.status(HttpStatus.CREATED)
.body(created);
}
Spring triggers validation before the method processes the request. Invalid input can then be translated into the API’s standard validation error format.
Standardize error responses
Modern Spring Framework versions support ProblemDetail for HTTP error responses. A centralized exception handler can provide consistent information:
@RestControllerAdvice
public class ValidationExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ProblemDetail> handleValidation(
MethodArgumentNotValidException exception) {
ProblemDetail problem =
ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
problem.setTitle("Validation failed");
problem.setDetail(
"One or more request fields are invalid.");
return ResponseEntity
.badRequest()
.body(problem);
}
}
This example provides a general validation message. A production API may also include field-level validation details in a consistent extension property, while ensuring the response does not expose unnecessary internal information.
Separate request and response models
A request model describes what the client is allowed to submit. A response model describes what the API returns.
Avoid returning persistence entities directly when doing so would expose internal fields or couple the API contract to the database schema.
Separate DTOs allow the application to change its internal implementation without unnecessarily breaking clients.
Choose status codes consistently
Use appropriate status codes for successful creation, validation errors, missing resources, authorization failures, and conflicts.
Clients should be able to distinguish these conditions without parsing arbitrary message text.
Document the contract
Springdoc OpenAPI can generate API documentation from Spring application metadata and annotations. Documentation should reflect the actual request models, response schemas, status codes, and authentication requirements.
Automated tests can then verify that important response contracts remain stable as the application evolves.
Conclusion
Reliable Spring Boot APIs combine declarative validation, separate request and response models, centralized error handling, and consistent status codes. Treat the API contract as a deliberate design decision rather than something that emerges independently in each controller.