Spring WebFlux Flux behavior with non streaming application/json
In the case of a streaming mimetype (application/stream+json
), the JSON codec configured by default in Spring WebFlux will serialize to JSON and flush on the network each element of the Flux
input. This behavior is handy when the stream is infinite, or when you want to push information to the client as soon as it's available. Note that this has a performance cost, as calling the serializer and flushing multiple times takes resources.
In the case of a non-streaming type (application/json
), the JSON codec configured by default in Spring WebFlux will serialize to JSON and flush to the network in one go. It will buffer the Flux<YourObject>
in memory and serialize it in one pass.
This doesn't mean the operation is blocking, since the resulting Flux<Databuffer>
is written in a reactive fashion to the network. nothing is blocking here.
This is just a tradeoff between "streaming data and using more resources" vs. "buffering and using resources more efficiently".
In the case of streaming, things are more likely to be processed by different worker threads, since work items are available at different intervals. In the case of the simple JSON response - it might be processed by one or more threads as well: it depends on the payload size, if the remote client is slow or not.
It seems that all magic is happening inside AbstractJackson2Encoder#encode method.
This is the code for the regular application/json
serialization:
// non-streaming
return Flux.from(inputStream)
.collectList() // make Mono<List<YourClass>> from Flux<YourClass>
.map(list -> encodeValue(list, bufferFactory, listType, mimeType, hints)) // serialize list to JSON and write to DataBuffer
.flux(); // get Flux<DataBuffer> from Mono<DataBuffer>
So, yes it waits for the Flux to terminate before serializing.
Performance improvements are questionable because it always has to wait all data to serialize. So this no much difference between Flux or regular List
in the case of application/json
media type