feat(ext-jackson): one module per data format, bodies checked on the way in

flash-ext-jackson and flash-ext-validation become three modules:

- flash-ext-jackson-core: the Codec (one mapper, body/write/writeView),
  JacksonHandler, the outbound marshalling, and the constraint engine that
  used to be flash-ext-validation
- flash-ext-jackson-json: Json, JsonExtension, JsonHandler
- flash-ext-jackson-xml: Xml, XmlExtension, XmlHandler

Every Jackson format is the same databind model behind a different factory, so
the annotations, the constraints and the published schema are the same for all
of them: only the mapper and the content type differ, and that is all a format
module says. A route picks its format by the handler it extends — there is no
negotiation and nothing to configure.

A typed body is now always verified against its own type's jakarta
constraints, whatever the format: malformed is a 400, a broken constraint is a
422, and neither reaches the handler. The validator was already allocation-free
and stays so; validating is no longer something an application remembers to do.

bodyFrom is gone. body has the streaming semantics, because the request's
stream is reused per connection while bytes() allocates the whole body: one
name, the path that does not allocate. JacksonExtension is JsonExtension, and
autoJson() is auto().

The root POM now manages every module of this build, so anything composing
Flash imports it once and never names a version again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Zakaria El Orche
2026-09-23 13:31:28 +00:00
co-authored by Claude Opus 5
parent ef4740f26d
commit adcd6376b6
37 changed files with 894 additions and 801 deletions
+6 -4
View File
@@ -9,7 +9,9 @@ a zero-allocation FSM router, bounded protocol state, and one shared request/res
|---|---|
| `flash` | Core server library — HTTP/1.1 and HTTP/2 transport, router, request/response model |
| `flash-testing` | JUnit 5 harness — boot an app on an ephemeral port, fake its services, assert on responses |
| `flash-extensions/flash-ext-jackson` | Jackson JSON integration |
| `flash-extensions/flash-ext-jackson-core` | What every Jackson format shares: the codec, the body handler, the constraints a body is checked against |
| `flash-extensions/flash-ext-jackson-json` | JSON bodies and responses |
| `flash-extensions/flash-ext-jackson-xml` | XML bodies and responses |
| `flash-extensions/flash-ext-openapi` | OpenAPI 3.0 spec + Swagger UI |
| `flash-extensions/flash-ext-security-core` | Security: authentication chain, annotations, sessions, OpenAPI |
| `flash-extensions/flash-ext-security-oidc` | OpenID Connect: bearer tokens, code flow + PKCE |
@@ -23,7 +25,6 @@ a zero-allocation FSM router, bounded protocol state, and one shared request/res
| `flash-extensions/flash-ext-view-thymeleaf` | Opinionated Thymeleaf SSR extension |
| `flash-extensions/flash-ext-vite` | Vite frontend: dev server in DEV, the built SPA from the jar otherwise |
| `flash-extensions/flash-ext-vite-maven-plugin` | Builds the Vite frontend into the jar during `mvn package` |
| `flash-extensions/flash-ext-validation` | Request validation — jakarta constraints, compiled once per type |
| `flash-extensions/flash-ext-scheduler` | Interval and cron background jobs on virtual threads |
| `flash-extensions/flash-ext-cache-core` | Caching contract — `Cache`, `CacheManager`, `CacheSpec` |
| `flash-extensions/flash-ext-cache-caffeine` | In-process cache backed by Caffeine |
@@ -151,7 +152,9 @@ FlashApp.create(8080)
```
See extension-specific READMEs for full details:
- [`flash-ext-jackson`](flash-extensions/flash-ext-jackson/README.md)
- [`flash-ext-jackson-core`](flash-extensions/flash-ext-jackson-core/README.md)
- [`flash-ext-jackson-json`](flash-extensions/flash-ext-jackson-json/README.md)
- [`flash-ext-jackson-xml`](flash-extensions/flash-ext-jackson-xml/README.md)
- [`flash-ext-openapi`](flash-extensions/flash-ext-openapi/README.md)
- [`flash-ext-security-core`](flash-extensions/flash-ext-security-core/docs/README.md)
- [`flash-ext-security-oidc`](flash-extensions/flash-ext-security-oidc/docs/README.md)
@@ -161,7 +164,6 @@ See extension-specific READMEs for full details:
- [`flash-ext-mcp`](flash-extensions/flash-ext-mcp/docs/README.md)
- [`flash-ext-view-jte`](flash-extensions/flash-ext-view-jte/README.md)
- [`flash-ext-view-thymeleaf`](flash-extensions/flash-ext-view-thymeleaf/README.md)
- [`flash-ext-validation`](flash-extensions/flash-ext-validation/docs/README.md)
- [`flash-ext-scheduler`](flash-extensions/flash-ext-scheduler/docs/README.md)
- [`flash-ext-cache-caffeine`](flash-extensions/flash-ext-cache-caffeine/docs/README.md)
- [`flash-testing`](flash-testing/docs/README.md)