Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ricpalomino/spring-boot/llms.txt

Use this file to discover all available pages before exploring further.

The Products API validates all incoming create and update request bodies using Jakarta Bean Validation annotations declared directly on ProductRequestDTO. When a request body fails validation, Spring automatically throws MethodArgumentNotValidException before your controller logic runs. GlobalExceptionHandler catches that exception and converts it into a structured 400 response with a field-level error map—no try-catch required in your controller.

ProductRequestDTO

@Setter
@Getter
public class ProductRequestDTO {

    @NotBlank(message = "Nombre del proudcto es requerido")
    @Size(min = 3, max = 100, message = "El nombre del producto debe tener entre 3 y 100 caracteres")
    private String name;

    @Min(value = 1, message = "El precio del producto debe ser mayor a 0")
    private Double price;

    public ProductRequestDTO() {}

    public ProductRequestDTO(String name, Double price) {
        this.name = name;
        this.price = price;
    }
}

Validation constraints

FieldAnnotationRuleError message
name@NotBlankMust not be null, empty, or whitespace-onlyNombre del proudcto es requerido
name@Size(min=3, max=100)Length must be between 3 and 100 charactersEl nombre del producto debe tener entre 3 y 100 caracteres
price@Min(1)Must be 1 or greater (effectively > 0 for a Double)El precio del producto debe ser mayor a 0
All three constraints fire independently. If both name and price are invalid, the 400 response includes an entry for each failing field.

What happens on a validation failure

When the request body violates one or more constraints, the API returns HTTP 400 with the following JSON shape:
{
  "responseCode": "400",
  "responseMessage": "Error de validación",
  "data": {
    "name": "El nombre del producto debe tener entre 3 y 100 caracteres"
  }
}
The data object is a Map<String, String> where each key is the failing field name and each value is the constraint’s message attribute. Multiple failures appear as multiple keys in the same map.

Example: sending a bad request

The following request omits price and passes a name that is too short:
curl -X POST http://localhost:8080/api/v1/products \
  -H "Content-Type: application/json" \
  -d '{"name": "AB", "price": 0}'
Response:
{
  "responseCode": "400",
  "responseMessage": "Error de validación",
  "data": {
    "name": "El nombre del producto debe tener entre 3 y 100 caracteres",
    "price": "El precio del producto debe ser mayor a 0"
  }
}
Both fields fail simultaneously, and the client receives a single response that lists every issue.

Activating validation in the controller

Bean Validation only runs automatically when the controller method parameter is annotated with @Valid. Without it, the annotations on ProductRequestDTO are ignored and no validation occurs. Confirm that your controller methods that accept a ProductRequestDTO include @Valid:
@PostMapping
public ResponseEntity<ApiResponse<ProductResponseDTO>> createProduct(
        @Valid @RequestBody ProductRequestDTO dto) {
    ...
}

Extending with additional constraints

You can add more Jakarta Bean Validation annotations to ProductRequestDTO without touching the controller or the error handler. Common additions include:
  • @DecimalMax / @DecimalMin on price to cap the maximum allowed value
  • @Pattern on name to restrict to alphanumeric characters
  • @NotNull on price to make the field explicitly required (currently a missing price defaults to null and skips the @Min check)
After adding annotations, the 400 response automatically includes the new field’s error message—no other code changes are needed.

Build docs developers (and LLMs) love