Spring Boot: From Basics to Production · Building REST APIs with Spring MVC
DTOs with Records and JSON Mapping
Model requests and responses with Java records and control JSON output.
Java records are ideal DTOs: immutable, concise, with built-in equals/hashCode. Use separate request and response records, map between entities and DTOs in services (manually or with MapStruct), and configure Jackson for dates (ISO-8601), naming and unknown properties. Annotations like @JsonProperty and @JsonInclude(NON_NULL) fine-tune output.
public record CreateProductRequest(
@NotBlank @Size(max = 200) String name,
@NotNull @PositiveOrZero Long priceCents,
@NotBlank String currency) {}
@JsonInclude(JsonInclude.Include.NON_NULL)
public record ProductResponse(long id, String name, long priceCents, String currency, Instant createdAt) {
static ProductResponse from(Product p) {
return new ProductResponse(p.getId(), p.getName(), p.getPriceCents(), p.getCurrency(), p.getCreatedAt());
}
}
Common pitfalls
- Using
doublefor money. - One DTO for create, update and response (clients can set server-controlled fields).
- Leaking internal enums or IDs you may want to change later.
Key points
- Records as DTOs
- Separate request/response types
- Instant/ISO-8601 for timestamps
Further reading: Spring Boot: JSON
Practice questions
Why are records good DTOs?
Answer
They're immutable, concise, and their components define the JSON shape clearly; Jackson supports them natively.
Why separate CreateProductRequest from ProductResponse?
Answer
Requests shouldn't include server-generated fields (id, createdAt), and responses may include computed or related data; separate types keep the contract explicit and safe.
Open in the app to mark lessons complete, take notes and track your progress.