problem-details-core
The RFC 9457 model and the JSON codec. This is the only module a library or an application needs in order to build and read problem documents; the other three add a wire format or a framework.
Depends on kotlinx-serialization-json and nothing else.
Where to start
Build a document with the io.github.ilyankin.rfc9457.problem builder, or with io.github.ilyankin.rfc9457.Problem directly when every member is already known. Encode and decode with kotlinx.serialization.json.Json — io.github.ilyankin.rfc9457.Problem carries its own serializer, so no converter has to be registered and no foreign converter can win the type.
The one thing worth knowing before reading further
Extension members (RFC 9457 §3.2) are written as siblings of the five standard members, never nested under an extensions key. The extensions map is how they are held in memory; it is not a member of the wire format. Several published implementations get this wrong, and a consumer reading {"extensions": {...}} is reading a non-conforming document.
Throwing a problem
io.github.ilyankin.rfc9457.ProblemException carries a io.github.ilyankin.rfc9457.Problem and adds nothing to the wire format, so domain code can raise one without depending on a web framework:
throw OutOfCredit.exception(detail = "Your current balance is 30, but that costs 50.")It carries a problem rather than being one. Making io.github.ilyankin.rfc9457.Problem an interface would allow the other shape, at the cost of the model's value semantics — copy, equals, destructuring — and of the single concrete type both codecs serialize; nothing here substitutes an exception where a document is expected, so that trade buys nothing. It is final for a separate reason: io.github.ilyankin.rfc9457.ProblemType already declares a problem type once, and a subclass would restate that type's URI, title and status beside it.
Reach for it when the document is assembled at the throw site. To turn an existing exception type into a problem, map it in the problem-details-ktor catalog instead — that keeps the exception free of any dependency on this library.
problem-details-ktor answers a thrown one with the document it carries.