WebFlux is not for the faint of heart
I started a project recently using Spring WebFlux which is based upon Project Reactor. I chose this one because it was new and I thought for the client it would suit the best as a lot of data was involved.
Reactive Programming
The concept this framework is based on is reactive programming. This means you effectively set up conveyor belts on which data will sit and be passed around a factory as part of a chain of operations that will make the raw material into the end product you want.
You get the record from the database, pass it along to the service to transform it into a DTO
and then pass it to the controller that transforms it into a HTTPResponse
for example.
All of this is non blocking I/O. From the database to the response to the user. This means the CPU is always doing something to progress one process or another. I quite liked this feature. The problem is building these conveyor belts.
Data flow
The flow is sometimes difficult to visualise. It does not help that you can only start flows buy so called subscribing. Then sometimes you want to do two things with the data at two different places but you cannot easily do that. In normal non reactive programming you would for example create a variable that holds some data and send that data to two functions. You could do that asynchronous with CompletableFuture
or just regular old synchronous.
I had a hard time grasping every thing and sometimes when things did not work it was because of the flow being wrong or incorrect. Especially when handling errors and stopping the flow. I learned you should handle errors and then send along null
s for example as the next one will not get the null
. Optional
s might also work but provides more work checking it later in the flow, downstream.
Keep it small
If you keep the functions themselves as small as possible and named correctly you can at least read the flow in a understandable way. It is also important to make it simple at the top and more and more complex the deeper you go. This means if you understand abstractly what needs to happen and then it does not happen you go one layer deeper. Usually the lowest level is fine, i.e. getting the data from some resource. The top level is usually also fine, i.e. sending the response to the user.
It is that middle bit where you do the transformations and business logic where it seems to often go awry.
Adding new functionality to an existing flow is simple and complex at the same time. You have to make sure you give back the same output as before or make sure the input of the next step gets adjusted. It makes it quite finicky to correctly in one try insert new steps.
I would recommend it to at least try out. It might not suit your style, but it does give some great concepts in structuring your application and data flows.