Real-time Stocks App in React: Part 4

The application now works with the minimal requirements to display real-time stocks data. In this post I will discuss how I added a limiter feature for incoming asynchronous data!

For reference, the repository is available at github.com/giltroymeren/stocks-app-ts.

Table of Contents

What is “rate limiting”?

Dai perfectly describes this process, in the context of software development, as:

Rate limiting protects your APIs from inadvertent or malicious overuse by limiting how often each user can call the API. Without rate limiting, each user may make a request as often as they like, leading to “spikes” of requests that starve other consumers. Once enabled, rate limiting can only perform a fixed number of requests per second. A rate limiting algorithm helps automate the process.

In our case, the API, where the stock data comes from, gives fast data albeit asynchronous every second to our WebSocket listener. The app needs a way to control these incoming messages in terms of scalability when the number of ISINs being tracked increase further.

Add a rate limiter to the updates

I decided to implement the rate limiter to the action that updates the stock data in the UI - updateStock.

Currently, when the websocket receives responses, it immediately calls updateStock and the UI re-rendered:

webSocket.current.onmessage = function (event: any) {
  console.info('Receiving message')

  updateStockList(JSON.parse(event.data))

The theory is to wrap updateStock in a rate limiter and execute it given a parameter of let’s say one second. Based from my research, the lodash package’s throttle method fits the bill.


Stocks App - Rate limited updateStock method diagram


Install and add lodash to the dependencies:

npm install --save lodash @types/lodash

Create a new method to wrap updateStock in the StockProvider class:

const throttledUpdateStockList = useRef(
  throttle((data: IStockItem) => updateStockList(data), 1000)
).current

throttle takes in a function and a time period in milliseconds as parameters. This entire declaration is also wrapped in a useRef hook as Rippon suggested to prevent multiple declarations between component renderings.

We can now replace the unwrapped update method in the websocket:

webSocket.current.onmessage = function (event: any) {
  console.info('Receiving message')

  throttledUpdateStockList(JSON.parse(event.data))

Boostrap for design

This is just a minor detail but I added the Twitter Bootstrap design system through CDN.


Stocks App - Home Page


Improvements

This is a small app with a ton of limitations (for now) and possibilities. Here are some of my future tasks to add when I have more time:

  • add unit tests for the components and state management
  • add validation for the SearchBar in case of empty or duplicate ISIN
  • disable the subscribe/unsubscribe buttons of StockItems depending on the process currently running
  • further polish the rate limiter to scale with more stocks
  • connect to another API to retrieve the entity name of the ISINs
  • improve the stock table updates by showing if the amounts were higher, lower or had no changes based on the previous value (could be change in color or addition of “+”/”-“ symbols to indicate)
  • separate the entire WebSocket entity from the provider and put them in their own file
  • replace the context with Redux for state management and set the WebSocket as a formal middleware

References

Twitter, LinkedIn