Reactive programming is used to handle asynchronous, non-blocking operations efficiently, allowing systems to scale and respond faster under high load.
Example of load testing on reactive vs imperative code
@RestControllerpublicclassReactiveController{privatefinalList<String> users =List.of("Alice","Bob","Charlie");@GetMapping("/users-reactive")publicFlux<String>getUsers(){ // Simulate a delay (e.g., simulating a network call or DB access)returnFlux.fromIterable(users).delayElements(Duration.ofMillis(100));// Delay each element by 100ms}}
@RestControllerpublicclassImperativeController{@GetMapping("/users-imperative")publicList<String>getUsers()throwsInterruptedException{ // Simulate some processing or latencyThread.sleep(100);// Optional: simulate delay for testingreturnList.of("Alice","Bob","Charlie");}}
After running the service, I used a program called 'hey' to perform local load testing on the APIs.
It can be seen that because of the non-blocking behavior, the reactive controller performs better.