nurkiewicz / nurkiewicz.com

https://nurkiewicz.com
10 stars 6 forks source link

JSON streaming and error handling with Spring WebFlux #19

Open utterances-bot opened 2 years ago

utterances-bot commented 2 years ago

JSON streaming and error handling with Spring WebFlux

Podcast for developers, testers, SREs… and their managers. I explain complex and convoluted technologies in a clear way, avoiding buzzwords and hype. Never longer than 4 minutes and 16 seconds.

https://nurkiewicz.com/2021/08/error-handling-in-json-streaming-with-webflux.html

rstoyanchev commented 2 years ago

Thanks for the excellent write-up. It is a pleasure to read writing like this that is distilled and made easy to read and follow. A few comments in response to points raised.

For TTFB, the response is delayed until the first data item in order to keep it not committed and allow an @ExceptionHandler method to handle it.

If an error occurs after emitting starts, indeed there is nothing more to do than but abruptly close, This is where it becomes evident that SSE and NDJSON are very basic in contrast to RSocket with proper support for streaming, including features such as error and cancellation signals, heartbeats, back pressure, resumption, etc.

For JSON arrays and collectToList, there is a trade-off between the overhead of serializing each item via Jackson individually vs collecting and serializing the entire List, especially for smaller items. Some further context here https://github.com/spring-projects/spring-framework/issues/19662#issuecomment-453450110. This is why we separated streaming from arrays more formally to provide control. A client can choose NDJSON for a large array and either aggregate on the client side or handle it as events, but otherwise it would be sent as a whole by default.

We could consider further improvements in this area, such as allowing the server to decide when a Flux should be streamed or not but again it is a trade off and it's hard for a framework to decide.

For the content-length on application/json and Flux, you have a point there. We seem to be a bit in a bind there due to the contracts between components but should be able to find a way to set it.

For SSE vs NDJSON, the former is primarily for use in browsers although nothing really prevents it from being used otherwise, but NDJSON requires less parsing and therefore is easier to support in various client-side tools or libraries.