Intro to API designing with Reactive Programming Paradigm

aditya goel
7 min readDec 30, 2022

--

In case you are landing here directly, it’s advisable for you to read this article and this article first, but it’s not that die-hard requirement as you still would be able to follow this blog.

Question:- What is Reactive programming ?

Question:- What is the meaning of declarative way of Programming ?

Answer → This is what I want to happen and then something is going to make it happen.

Question:- What’s the wikipedia definition of Reactive Programming ?

Question:- What’s the relationship between Async and Reactive Programming ?

Answer → Reactive Programming doesn’t necessarily implies Async. We can have Reactive Programming, which is Synchronous too. These 2 are separate concepts.

Question:- What are the use-cases of Reactive Programming ?

Answer → Classic use-case for Reactive Programming is Events. Although, we do have Swing, Java-Fx, etc. but still, of-course Java is not the first choice, while working with the Front-Ends. For example →

  • When some user clicks on the some button at UI/website, we perform some action i.e. we invoke some function. This is none other than the Reactive Programming. This is none different than Reaction to some event.
  • When some file is being read and it is complete, then we go and do some action.

Basically, some Trigger leads us to do some thing here. We are reacting to some trigger.

Question:- How does traditional Server side Web-development works ?

Question:- What are the characteristics of current day modern applications ?

Question:- With modern applications, how do we do scaling ?

Question:- Let’s see the below code and identify, what are the problems with this code-piece ?

Here, there are two calls that we are making :-

  • First, at line no. 1, we are issuing a call to the userService. The thread which is executing this statement, is just waiting. Once it returns, then only this thread proceeds.
  • Now, at line no. 2, again another call is being made and again this thread waits. After the second call too returns the response, we proceed further.
  • Finally, at line no. 3, we combine the results and return the response.

In an ideal scenario, the statement no. 2 doesn’t have to really wait for the statement no. 1 to complete, but it’s just waiting un-necessarily. So, the problem in above code is that, the two statements (1 and 2) are un-necessarily sequential and the threads are Idling (i.e. Thread is waiting un-necessarily).

Question:- What’s the biggest cost associated with the above programming fallacies and who has to ay that cost ?

Answer → The cost of this problem is that, we are penalising on the performance to the User (i.e. the one person, who made this request).

Question:- What’s the another issue with the above programming fallacy ?

Answer → Let’s understand the working of a typical web-server :-

  • Whenever any request comes-in, the web-server spawns a thread to handle that request end-to-end.
  • For example → there are three requests (originated from three different users) being shown below and there are three different threads, taking care of these requests.

Now, the problem here is that :-

  • The longer it takes for a thread to respond to Request, the more likely is that, there are multiple threads on the server. So, threads just keeps piling and adding.
  • At some point in time, web-server is going to tell that, I am not going to take on any additional request, as that’s my capacity to handle the traffic.

In nutshell, we are actually letting the thread-A to wait un-necessarily on statement no. 1 (getUser() function) to complete. If that thread would not have waited on the server, then this thread would not had been idle on the server and this thread could have handled another request.

Question:- What do we usually do, to solve this problem, as on current date ?

Answer → We would be doing Scaling i.e. we shall be :-

  • Either adding more machines i.e. Horizontal Scaling.
  • Or Scaling up our existing machine i.e. Vertical Scaling.

Question:- What’s the another big problem associated with this programming practice ?

Question:- What’s our programming behaviour with Imperative Coding Style so far with Spring Boot Framework ?

Question:- Does Concurrency APIs also provides an alternative to the Sequential Programming Style ?

Answer → CompletableFuture is an API, that’s available since very long time since JDK8. It implements the Future interface and works with CompletionStage to coordinate async operations.

Whenever userService.getUser(userId) operation completes, this object userAsync is going to inform us, about the same.

Question:- Can you showcase, how our original code would look like with Futures and whether this is best solution ? If not, are there any problems with the Futures ?

Answer →

  • At line no. 3, we are passing a command which means that, Go and Execute this code-line to invoke userService, but don’t bother me.
  • At line no. 5, we are passing an another command which means that, Go and Execute this code-line to invoke userPreferencesService, but don’t bother me.
  • At line no. 7, we are forming an another Future Object, which combines the above 2 future objects.
  • At line no. 9, join() command means that, we are going to wait for both of the future commands until they completes.
  • At line no. 10, we are fetching the User object from the userAsync future object.
  • At line no. 11, we are fetching the UserPreferences object from the userPreferencesAsync future object.
  • The advantage here is that, both of the calls (i.e. call to userService and call to userPreferencesService) runs in parallel, but at line no. 10, the join() operation is none other than blocking.
  • We need to wait for both of the service-calls (i.e. call to userService and call to userPreferencesService) to finish and then we return the response back. This is because, the returnType of the method getUserDetails is User object.
  • This means that, our code (API : /users/{userId}) has to wait, until the object of type User is prepared. We can’t return the response until the entire User object is ready & prepared. We need the User object here.

This code is little optimised, but still there is a room for improvement here, because still number of threads piles-up at the server. And This is the problem.

The solution to this problem is defined as follows :-

Question:- Can you demonstrate, how our API-code would be different with Reactive Programming paradigm ?

Answer → Note here that :-

  • We are no-more returning the User type of object, rather we are now returning the Mono<User> type of object.
  • The calls to two services (i.e. call to userService and call to userPreferencesService) have been parallelised and the below code is no-more blocking.

Question:- What are advantages with Reactive Programming paradigm ?

Question:- Explain Reactive Programming paradigm ?

Question:- What are the precautions, that we should take care while coding with Reactive-Programming ?

Answer → We should not be choosing this paradigm, if the application is not going to have enough load/foot-fall.

  • There is a little bit of learning-curve for the Reactive-Programming paradigm and the benefits of using the Reactive-Programming grows only once the project size grows to certain level.
  • Up until that tipping point, the benefits of the Reactive-programming are not that noticeable. The Reactive Programming is not the solution to everything.

References :-

--

--