Define reusable RFC 9457 problem types in Java. Codes keeps the type, status, and title consistent across error responses, with a dependency-free core and an optional Spring adapter.
Java 17+. Add one of these to your Gradle dependencies block:
Core:
implementation("io.github.aalsanie:codes:0.4.0")Spring (also includes codes):
implementation("io.github.aalsanie:codes-spring:0.4.0")Spring applications supply Spring Web; codes-spring does not include it transitively. Core · Spring on Maven Central.
Define a problem type once:
static final ProblemType ORDER_NOT_FOUND = ProblemType.of(
URI.create("https://api.example.com/problems/order-not-found"),
404,
"Order not found"
);With Spring, create a new occurrence with its own detail:
ProblemDetail problem = ProblemDetails.forTypeAndDetail(
ORDER_NOT_FOUND,
"Order o-123 was not found."
);ProblemDetails.forType(...) creates an occurrence without a detail. Return the result from a Spring exception handler; Spring handles the HTTP response.
Codes requires an absolute type URI other than about:blank, an HTTP status from 100 to 599, and a non-blank title. Exception handling and occurrence-specific data remain application concerns.
Spring integration · Problem type contract · Compatibility · Contributing
NOTE: If an application only creates one or two ProblemDetail instances directly, a local helper may be simpler.