Situation:
- I have a non-reactive legacy library which expects an
OutputStream
and writes its output into it, the method signature is something likevoid produceData(OutputStream stream)
- I want to expose the output from the method via a web service as a PDF file
- The file can be sometimes very large
- I am using the reactive framework Spring WebFlux
Motivation:
- I want my code to stay "as reactive as possible"
- I do not want to allocate a byte array for all the data at once, I want to maximally exploit the fact that the legacy method writes the output to
OutputStream
Question:
- What is the correct reactive pattern in WebFlux to return a large file in general?
- What is the correct reactive pattern in WebFlux to return a large file when the source of the data is a non-reactive method writing to a given
OutputStream
? - I should also be able to let the client understand that the output from the web service is a PDF file with a proper name.
What I am considering:
Mono<ByteArrayResource> getData()
- I don't want to use it because I would have to allocate the byte array for the whole content.- In the non-reactive world, I would just inject the
ServletResponse
object into the controller method and passed its output streamServletResponse.getOutputStream()
to my legacy method, but I don't know how to do this in the reactive world and if it is even recommended at all. Mono<DataBuffer> getData()
- In the controller code, I can easily obtain a newDataBuffer
from aDefaultDataBufferFactory
and use itsasOutputStream()
method, but then I don't know how to handle properly so theDataBuffer
is released after the data are consumed by the client.
What is the correct reactive pattern to handle situations like this?