Skip to content
aalsaniePublic

About

A lightweight Java library for reusable RFC 9457 problem type definitions.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

12 stars

Watchers

0 watching

Forks

Latest commit

 

History

73 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Codes

Maven Central CI License

Codes is a lightweight Java library for reusable RFC 9457 problem type definitions.

Spring provides ProblemDetail for an individual error occurrence. Codes provides the stable definition that can be reused across controllers, exception handlers, tests, and documentation.

ProblemType ORDER_NOT_FOUND = ProblemType.of(
    URI.create("https://api.example.com/problems/order-not-found"),
    404,
    "Order not found"
);

With Spring:

ProblemDetail problem = ProblemDetails.forType(ORDER_NOT_FOUND);

or with occurrence-specific detail:

ProblemDetail problem = ProblemDetails.forTypeAndDetail(
    ORDER_NOT_FOUND,
    "Order o-123 was not found."
);

The resulting problem keeps the reusable definition stable:

{
  "type": "https://api.example.com/problems/order-not-found",
  "title": "Order not found",
  "status": 404,
  "detail": "Order o-123 was not found."
}

Install

Core:

dependencies {
    implementation("io.github.aalsanie:codes:0.4.0")
}

Spring:

dependencies {
    implementation("io.github.aalsanie:codes-spring:0.4.0")
}

All artifacts require Java 17+.

The core artifact has no runtime dependencies and publishes no Maven dependencies. codes-spring depends on the core artifact but does not impose a Spring Framework version; the application supplies Spring Web.

Define a problem catalog

A problem type is an immutable value. Define reusable application problem types as constants:

final class OrderProblems {
    static final ProblemType ORDER_NOT_FOUND = ProblemType.of(
        URI.create("https://api.example.com/problems/order-not-found"),
        404,
        "Order not found"
    );

    static final ProblemType ORDER_ALREADY_CANCELLED = ProblemType.of(
        URI.create("https://api.example.com/problems/order-already-cancelled"),
        409,
        "Order already cancelled"
    );

    private OrderProblems() {
    }
}

Codes requires an absolute type URI, rejects about:blank, requires an HTTP status from 100 through 599, and requires a non-blank title. Use Spring's native ProblemDetail.forStatus(...) for status-only about:blank responses.

Different application exceptions can then reuse the same public problem type:

@ExceptionHandler(OrderNotFoundException.class)
ProblemDetail handleOrderNotFound(OrderNotFoundException ex) {
    return ProblemDetails.forTypeAndDetail(
        OrderProblems.ORDER_NOT_FOUND,
        "Order " + ex.orderId() + " was not found."
    );
}

@ExceptionHandler(ArchivedOrderNotFoundException.class)
ProblemDetail handleArchivedOrderNotFound(ArchivedOrderNotFoundException ex) {
    return ProblemDetails.forTypeAndDetail(
        OrderProblems.ORDER_NOT_FOUND,
        "Archived order " + ex.orderId() + " was not found."
    );
}

The library does not own exception handling, controller advice, localization, extension properties, or request-specific data. Those remain application and Spring concerns.

When to use Codes

If an application only creates one or two ProblemDetail instances directly, a local helper may be simpler.

Codes is useful when problem types are part of the API contract and need to be defined once and reused consistently across multiple handlers, modules, tests, or documentation.

Reference

License

Apache License 2.0.

About

A lightweight Java library for reusable RFC 9457 problem type definitions.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages