Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/t1/problem-details

Problem Details [RFC-9457] Java API, TCK, and implementations for JAX-RS and (currently not) Spring Boot
https://github.com/t1/problem-details

jax-rs microprofile microprofile-restclient rfc-7807 rfc7807 spring-boot

Last synced: about 1 month ago
JSON representation

Problem Details [RFC-9457] Java API, TCK, and implementations for JAX-RS and (currently not) Spring Boot

Awesome Lists containing this project

README

        

= Problem Detail image:https://maven-badges.herokuapp.com/maven-central/com.github.t1/problem-details/badge.svg[link=https://search.maven.org/artifact/com.github.t1/problem-details] image:https://github.com/t1/problem-details/actions/workflows/maven.yml/badge.svg[link=https://github.com/t1/problem-details/actions/workflows/maven.yml]

== Abstract

Map standard and custom exceptions to a http response body containing problem details as specified in https://datatracker.ietf.org/doc/html/rfc9457[RFC-9457] (formerly https://datatracker.ietf.org/doc/html/rfc7807[RFC-7807]).

Most things work out of the box: the `type` and `title` fields are derived from the exception class name; the `detail` field is the message of the exception; the `instance` field is a random UUID URN that is also logged together with the complete stack trace.

These defaults and the status code can be overridden with annotations.

I wrote a https://www.codecentric.de/wissens-hub/blog/rfc-7807-problem-details-with-spring-boot-and-jax-rs[blog] about this.

== Motivation

Getting a consistent error response format for a REST API is a common problem and allows clients to handle specific business errors. Getting some generic HTML response is not helpful. There is a standard for this type of details about an error: RFC-9457. And this library provides a simple way to map exceptions to this format.

== Spec & API

This has been proposed to and rejected by several existing specs:

* https://github.com/jakartaee/rest/issues/839[Jakarta REST (JAX-RS)]; a second discussion was also https://github.com/jakartaee/rest/issues/1150[rejected].
* https://github.com/eclipse/microprofile-rest-client/issues/248[MP REST Client].

The API in the `api` module looks quite stable. Some first ideas for a full spec follow below. It's yet far from complete, but it's a start:

* MUST `application/problem+json`, `application/problem+xml`; SHOULD any, e.g. `+yaml`
* SHOULD render `text/html`
* map also `@Valid` REST params
* logging: 4xx = DEBUG, 5xx = ERROR; configurable?
* order of extensions is alphabetic (which is better for tests than random)
* multiple extensions with the same name: undefined behavior
* JAXB can't unmarshal a subclass with the same type and namespace
* Security considerations: nothing dangerous in problem details (i.e. exception message); stack-trace in logs
* TODO scan client classpath for @Type annotated exceptions (and document this in the spec and the annotation)
* TODO inherited annotations
* TODO cause annotations
* TODO type factory, e.g. URL to OpenAPI
* TODO instance factory, e.g. URL to the logging system filtering on an UUID

== Dummy-Impl [ri]

It's called `ri`, but it's actually only a POC, and it's incomplete. See the README for details.

== Test

The `test` module runs integration tests by using https://github.com/t1/jee-testcontainers[JEE Testcontainers], i.e. it can be configured to start different Docker containers with various JEE application servers. By default, it starts a Wildfly.

`testcontainer-running`

As the containers don't yet implement the API by themselves, the dummy implementation `ri` is hard-wired in the tests for now.

=== Wildfly

Default `mvn` or explicitly `mvn -Djee-testcontainer=wildfly`

=== Open Liberty

`mvn -Djee-testcontainer=open-liberty:19.0.0.9-javaee8-java11 -Pwith-slf4j`

needs tag for jdk11 support
needs dependencies on slf4j-api and slf4j-jdk14

=== TomEE

`mvn -Djee-testcontainer=tomee`

3 tests fail, because this version of TomEE (9.0.20 / 8.0.0-M3) doesn't write the problem detail response entity in some cases for some reason:
StandardExceptionMappingIT.shouldMapWebApplicationExceptionWithoutEntityButMessage
StandardExceptionMappingIT.shouldMapWebApplicationExceptionWithoutEntityOrMessage
ValidationFailedExceptionMappingIT.shouldMapValidationFailedException

=== Payara

`mvn -Djee-testcontainer=payara -Pwith-slf4j`

fails due to lack of jdk11 support of the https://hub.docker.com/r/payara/server-full[`payara`] image.
needs dependencies on slf4j-api and slf4j-jdk14

== Spring

We build for JDK 11 and the Jakarta EE 10 APIs. The current versions of Spring Boot don't support this combination. But you can still use the older `com.github.t1:problem-details-api:1.0.10`, which was based on Jakarta EE 8.