dmx-fun 0.2.0 is out — and this one is special.
It is our first-anniversary release. The first commit landed on June 30th, 2025. One year
later, dmx-fun has grown from a handful of core types into a coordinated ecosystem of functional
programming modules for Java backends — shipped across 17 releases in that first year, from
0.0.1 all the way to the one you are reading about now.
Thank you to everyone who filed an issue, opened a pull request, or put dmx-fun into a real backend. This release is a celebration of that year — and a big step forward.
The headline: dmx-fun goes reactive
Until now, dmx-fun’s railway-oriented style lived in synchronous code. 0.2.0 extends it to the
reactive world with two new modules:
fun-reactor— Project Reactor interop: convertOption,Result, andTryto and fromMonoandFlux, and keep composing on the Result/Try track inside reactive pipelines.fun-spring-webflux— Spring WebFlux adapters: map your domain outcomes straight to HTTP responses, for both functional endpoints and annotation controllers.
Same idea you already know — failures, absence, and validation stay explicit in the type system —
now flowing through Mono and Flux.
fun-reactor — interop and railway operators
fun-reactor bridges dmx-fun and Project Reactor in both directions, and adds railway operators
so a Mono<Result<V, E>> stays on the happy path without unwrapping:
Mono<Result<User, ApiError>> user = ReactorResult.fromMono(userRepository.findById(id), ApiError::fromThrowable) .flatMapOk(u -> ReactorResult.fromMono(enrich(u), ApiError::fromThrowable)) .mapOk(User::redactSecrets);For collections, sequence aggregates a Flux<Result<V, E>> fail-fast, while collectValidated
accumulates every error instead of stopping at the first — the reactive counterpart of
Validated’s error accumulation.
fun-spring-webflux — outcomes to HTTP
fun-spring-webflux maps Option, Result, Try, and Validated to WebFlux responses with
documented, overridable HTTP conventions. Use WebfluxFun for functional endpoints:
RouterFunction<ServerResponse> routes() { return RouterFunctions.route() .GET("/users/{id}", request -> WebfluxFun.fromResult( userService.findById(request.pathVariable("id")), // Mono<Result<User, ApiError>> error -> ServerResponse.status(error.status()).bodyValue(error.detail()))) .build();}…or WebfluxEntity for annotation controllers (@RestController), returning a
Mono<ResponseEntity<…>>:
@GetMapping("/users/{id}")Mono<ResponseEntity<User>> user(@PathVariable String id) { return WebfluxEntity.fromOption(userService.find(id)); // Some -> 200, None/empty -> 404}The module goes well beyond a single mapping:
- Streaming and aggregation — collect a
Flux<Result>fail-fast, accumulate every error, or stream aFlux<V>element-by-element as NDJSON/SSE. - Customizable success responses — a
SuccessHttpMapperlets you return201 Createdwith aLocationheader,202 Accepted, caching headers, and so on. - RFC 7807 problem responses —
WebfluxProblemrenders failures as standardapplication/problem+jsonProblemDetaildocuments. - Spring Boot auto-configuration — with
fun-spring-booton the classpath, a ready-madeProblemDetailmapper bean is auto-configured, configurable and conditional.
Both fun-reactor and fun-spring-webflux declare Reactor and Spring as compileOnly — you
bring your own versions. spring-webflux is tested in CI against Spring Framework 6.0.x through
7.0.x on every pull request.
Also in 0.2.0
Result.mapCatching(CheckedFunction)— amapvariant that captures thrown checked exceptions as anErr, so throwing mappers no longer force you out of the Result track.NonEmptyList.reduce(...)andjoinToString(...)— ergonomic folds over a guaranteed non-empty list.- Dependency refresh — Spring Boot 4.1.0, Jackson 2.22.0, JUnit 6.1.1, Micrometer 1.17.0, Micrometer Tracing 1.7.0, Quarkus 3.37.0, Hibernate Validator 9.1.1.Final, and more.
See the full changelog for the complete list.
A year in numbers
- 17 releases —
0.0.1→0.2.0 - 1 stable milestone —
0.1.0, our first production-ready release - 13 modules — core types plus serialization, observability, resilience, HTTP, framework, and now reactive integrations
- 1 interoperability audit across every core type
From four types in a single artifact to a reactive-ready ecosystem — in twelve months.
Getting started
// Gradle (Kotlin DSL) — reactive stackimplementation(platform("codes.domix:fun-bom:0.2.0"))implementation("codes.domix:fun")implementation("codes.domix:fun-reactor")implementation("codes.domix:fun-spring-webflux")<!-- Maven --><dependency> <groupId>codes.domix</groupId> <artifactId>fun-spring-webflux</artifactId> <version>0.2.0</version></dependency>The Reactor guide and the Spring WebFlux guide walk through both new modules with real-world examples. Full Javadoc is at /dmx-fun/javadoc/.
Here’s to the next year.
Found a bug or have a suggestion? Open an issue on GitHub.
