(global) Single & Multi mapping

single & multi wrapper

When using WebFlux we like to wrap certain parameters & results types in reactive types like Mono<> or Flux<>.

To achieve this the processor knows two special mappings:

  • single: to wrap non-array like types (i.e. not a collection)

  • multi: to wrap array like types (i.e. a collection)

multi

map:
  multi: reactor.core.publisher.Flux

Which will use Flux<> as collection wrapper instead of the original java collection type for all list responses (or parameters). multi does not affect collections in model types.

single

To map non-array like responses to a Mono<> set the single mapping:

map:
 single: reactor.core.publisher.Mono

The processor will now wrap all non-array like response types with the given single mapping.

endpoint specific mapping

it is also possible to configure single & multi on the endpoint level.

single & multi with result mapping

It is possible to use single & multi mappings together with the result mapping, i.e. ResponseEntity.

result will wrap single

ResponseEntity<Mono<String>>

and multi

ResponseEntity<Flux<String>>

Unfortunately if you need the reactive result to modify the http response, something like this:

// does not work
public ResponseEntity<Mono<Result>> someEndpoint() {
    return someBean.getResult()
           .map(r -> ResponseEntity
                   .ok()
                   .eTag(r.eTag())
                   .body(Mono.just(r)));
}

it will not work because the result type of the statement is Mono<ResponseEntity<Mono<Result>>> and not the expected ResponseEntity<Mono<Result>>.

This can be fixed by modifying the result mapping to

openapi-processor-mapping: v8

options:
  # ...

map:
  # wrap the ResponseEntity with Mono
  result: reactor.core.publisher.Mono<org.springframework.http.ResponseEntity>

  single: reactor.core.publisher.Mono
  multi: reactor.core.publisher.Flux

which will now generate the endpoint signature as

public Mono<ResponseEntity<Mono<Result>>> someEndpoint() {
   // ...
}

and the above code will now work.

It is recommended to configure this on the endpoint level if you just need this for a few endpoints.

See also Spring ResponseEntity documentation.