liveBook · Manning

Mono

As explained in Spring in Action, Sixth Edition

Mono is Project Reactor's publisher type for asynchronously emitting zero or one element, including no element when parameterized with Void.

A Mono is Project Reactor’s publisher for a result that has at most one item. It can publish one value, complete without a value, or signal an error. Use Flux when a pipeline may publish many items. A Mono is a pipeline, not the value itself: operations describe what should happen as data flows through it. section 11.2 section 11.2.1

Mono.just("Craig")
    .map(n -> n.toUpperCase())
    .map(cn -> "Hello, " + cn + "!")
    .subscribe(System.out::println);

This small pipeline starts with one name, transforms it twice with map(), then subscribes to print the greeting. The successive map() calls create new Monos rather than changing the original one. section 11.2

Subscription starts the flow. For a standalone pipeline, call subscribe() or use StepVerifier to subscribe and check its result. In a Spring WebFlux controller, return the Mono instead; the framework subscribes for you. The controller can return before the repository has fetched its data. section 11.3.1 section 12.1.2

@GetMapping("/{id}")
public Mono<Taco> tacoById(@PathVariable("id") Long id) {
  return tacoRepo.findById(id);
}

A GET handler returns the repository’s Mono<Taco> directly. Compared with extracting a Taco from an Optional, the handler leaves the single-result response in the reactive pipeline. section 12.1.2

Common ways to use a Mono include:

  • Create one with Mono.just(value), or obtain one from a reactive repository or service. A Flux can produce a Mono containing a list with collectList(). section 11.3.1 section 11.3.3
  • Transform its value with map(). Use flatMap() when the next step itself returns a Mono, such as saving a received request body; flatMap() is also used with subscribeOn() for asynchronous transformations. section 11.3.3 section 12.1.2
  • Represent no item with Mono.empty(). A Mono<Void> is useful when an HTTP PUT or DELETE has no response payload. section 12.4.5 section 12.4.3
@PostMapping(consumes = "application/json")
@ResponseStatus(HttpStatus.CREATED)
public Mono<Taco> postTaco(@RequestBody Mono<Taco> tacoMono) {
  return tacoMono.flatMap(tacoRepo::save);
}

This POST handler accepts a Mono<Taco> request body. flatMap() passes its Taco to the repository’s save method and returns the resulting Mono<Taco>. section 12.1.2

For outgoing requests, WebClient’s bodyToMono(Ingredient.class) extracts a single response body into a Mono<Ingredient>. Subscribe to the resulting client pipeline for the request to be sent. When response headers also matter, exchangeToMono() can inspect them and return Mono.empty() instead of an ingredient. The same single-result pattern appears in reactive security: a user lookup can map Mono<User> to Mono<UserDetails>, while an empty result indicates no match. section 12.4.1 section 12.4.5 section 12.5.2

How Spring in Action, Sixth Edition covers it

How deep it goes
Explains creation, subscription, transformation, empty results, and framework integration with code; surveys selected operations rather than the full API.
Examples
Shows a greeting pipeline, single-taco controller, ingredient HTTP requests, and reactive user lookup.
What it assumes
Introduces Mono and Flux as publisher types before applying them; examples assume basic Java method calls, lambdas, and Spring controllers.
What you can do after
Apply it via Project Reactor and Spring WebFlux to transform and return single-result pipelines, and via WebClient to consume single responses.
How it connects
Connects Mono to Flux, Reactive Streams Publisher, map(), flatMap(), Spring WebFlux, WebClient, and ReactiveUserDetailsService.

Also explained in

Compare how 2 books explain Mono →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Spring in Action, Sixth Edition. The section links point to the parts of the book it draws on.