Careeroza
Records as DTOs
Request and Response Records
Java records are ideal DTOs: immutable, short, with equals, hashCode and toString for free. Jackson reads and writes them without extra annotations.
package com.shopease.product.dto;
import java.math.BigDecimal;
// What the client sends to create a product: no id, no audit fields
public record CreateProductRequest(String name, String description,
BigDecimal price, int stock, String category) {}
// What the client receives
public record ProductResponse(Long id, String name, String description,
BigDecimal price, int stock, String category,
boolean inStock) {}Nested DTOs and Custom JSON Names
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonInclude(JsonInclude.Include.NON_NULL) // skip null fields in the JSON
public record ProductSummary(
Long id,
String name,
@JsonProperty("mrp") BigDecimal price, // JSON name differs from Java name
CategoryRef category) {
public record CategoryRef(Long id, String name) {}
}Example
curl localhost:8080/api/products/1/summaryExample output
{"id":1,"name":"Wireless Mouse","mrp":799.00,"category":{"id":4,"name":"Electronics"}}Note: Jackson uses camelCase names by default. To use snake_case for the whole API set spring.jackson.property-naming-strategy=SNAKE_CASE.