Careeroza
Real World Example
DTOs for an Order API
In a Spring Boot backend, request and response bodies are perfect records: they are just data moving between layers. Here a service turns a request record into a response record with a computed total.
Example
import java.util.List;
public class Main {
record OrderItemRequest(String productId, int quantity, long unitPricePaise) {
OrderItemRequest {
if (quantity <= 0) throw new IllegalArgumentException("quantity must be > 0 for " + productId);
}
long lineTotal() { return quantity * unitPricePaise; }
}
record CreateOrderRequest(String customerId, List<OrderItemRequest> items) {
CreateOrderRequest {
items = List.copyOf(items); // defensive copy: truly immutable
}
}
record OrderResponse(String orderId, String customerId, int itemCount, String total) { }
static int nextId = 1000;
static OrderResponse create(CreateOrderRequest req) {
long total = 0;
for (OrderItemRequest item : req.items()) total += item.lineTotal();
return new OrderResponse("ORD-" + (++nextId), req.customerId(), req.items().size(),
String.format("Rs %d.%02d", total / 100, total % 100));
}
public static void main(String[] args) {
CreateOrderRequest req = new CreateOrderRequest("CUST-7", List.of(
new OrderItemRequest("P-101", 2, 49900),
new OrderItemRequest("P-205", 1, 129950)));
System.out.println(create(req));
try {
new OrderItemRequest("P-300", 0, 1000);
} catch (IllegalArgumentException e) {
System.out.println("400 Bad Request: " + e.getMessage());
}
}
}Output
OrderResponse[orderId=ORD-1001, customerId=CUST-7, itemCount=2, total=Rs 2297.50] 400 Bad Request: quantity must be > 0 for P-300