API client patterns every front-end developer need to know
·
1159
Wajdi Alkayal
API client patterns every front-end developer need to know
REST API is the de facto standard for the Web Application (client) to communicate with Backend Application (server).
REST API popularity increased due to its simplicity compared to well-established SOAP based Web services. GraphQL, which has clear specification and good community support, is currently playing second fiddle. “Sooner” the king RPC will be back 😃
Web Applications will need one or more of the following API client patterns. I will be using Axios and JS Promise for the demo
Basic asynchronous call
Orchestration
Split-Join with fail-fast / Split-Join with all-settled
Dynamic Split-Join
Controlled concurrency
Rat race
For demo, let’s use the following fake APIs provided by dummyapi.io
If we have to move immediately to the next step on failure of any one of the API calls, then use fail-fast.
All-Settled
There are use-cases where we have to wait till all API calls either are successful or failed. In such scenario use all-settled. This approach will give you absolute control.
Promise.all() will reject immediately upon any of the input promises rejecting. In comparison, the promise returned by Promise.allSettled() will wait for all input promises to complete, regardless of whether or not one rejects. Consequently, it will always return the final result of every promise and function from the input iterable. Source: MDN
4. Dynamic Split-Join
There are use-cases, where you will get dynamic list of data and have to make enrichment calls or some actions for each entry. In such situations, use dynamic split-join
The first example code is naive. Look for the potential problem. In the next example, I have provided a solution which involves a correlation id.
Naive example
Example with correlation logic is provided below. The logic shared is just one-way to do the correlation. If API provider supports, you can use custom header to pass on the correlation id and receive the same in response.
5. Controlled concurrency
In dynamic split-join example, I have limited the number of users to just 2, on purpose. Now, if we happen to get 10 or 60 users and we run dynamic split-join for all users, then the API server will get flooded with requests. Typically in production or in any public web site, there would be an API gateway which does rate-limit check and throw error. Controlled concurrency would be handy in these situations.
For any controlled executions or resource contention scenario, the common solution would involve some kind of Queue-Worker pattern or batching.
💡 Controlled concurrency use case is an indicator to improve your backend API design either following sideloading or embedded approach. Typically these will be handled in backend-for-frontend (BFF) layer in case more such lapses are prevalent or if the granular APIs are from product or third-party provider.
6. Rat Race
There are use cases such as “Search API” or similar where we might fire API call based on events (like text entered). There is subtle race conditions. We are assuming, the response would come in sequence. But in reality, the second request could come earlier than the first request.
I have named this pattern as Rat Race, just for fun 😅
💡Debounce and throttle will help to reduce the number API request fired, but will not help in avoiding the race condition
Solution to avoid this race condition is to cancel the previous request, before initiating the new one. Axios provides CancelToken for this purpose.
💡 Axios cancellation approach only averts the race condition on response path. Server could have received all the requests and might have processed.
One other pattern is stream. Axios (via XHR) currently does not support streaming. Fetch API supports.
In many situations, a slight improvement in API design or adoption of“backend-for-frontend (BFF) layer” could avoid complication in API client call. In all other cases, it would be better for front-end developer to prepare themselves for handling complex scenarios. Hopefully, these patterns would help you 😇