Let’s look at rate limiting/Throttle APIs on express application, their practical side, and also the way it is implemented through middleware.
But before looking at its implementation, let us see what rate limiting, throttling API is.
Introduction
Rate limiting is a technique to limit traffic in a server. It puts a cap on how often someone can repeat an action within a certain timeframe. Rate limiting can help stop certain kinds of malicious activities. One of its main use of limiting is to reduce the load on the server.
A common place where rate limiting is seen is the login function in most of the applications. The figure below shows the working flow of the login function, as it will clear out things about rate limiting, and API throttling.
In the above figure, the user during login has entered the wrong password 5 times, which is generally the limit when it comes to entering the passwords wrong. The user account is locked after 5 attempts, it was done to limit the times the user hits the login function. After the account is locked the user is not able to log in even if the password is correctly provided, without checking their email for the email that was sent by the application.
Overall rate limiting and throttling follow the same concept, in the above case the account being locked protected the user’s account from malicious access. In the case of rate limiting, it protects the server from the load received from the repeated requests it receives. The request and response flow of this process is shown in the figure below.
Fundamental Flow Of Rate Limiting
The client’s request is firstly handled by the rate-limiter function as shown in the above figure. Then the function checks if the client that sent the request has exceeded their limit or not. If the limit is not exceeded then the request is then redirected to the server, the server processes it, and returns the response back to the client. In the case where the client has exceeded the limit, the rate-limiter function returns back an error response back to the client without hitting the server at any rate of request sent by the client.
Now, that we have looked into rate limiting, and throttling, let’s see how it is implemented on an application that uses the Express framework.
Prerequisites
How do you throttle APIs on express?
To rate limit/throttle APIs on express, middleware can be used, as it works before a route it is placed at is invoked.
Here, we use a package that provides a middleware, the package is express-rate-limit. Let’s look at implementing the package.
Initializing Node.js application
## Creating a directory for rate limitting
$ mkdir express-api-throttle && cd express-api-throttle
## Initializing a the node project
$ npm init -y
Installing dependencies
## installing express
$ npm install express
## installing dependency that makes api throttling possible
$ npm install express-rate-limit
## installing dotenv for making use of environment varibles
$ npm install dotenv
## installing nodemon for making hotreload at code change possible
$ npm install --save-dev nodemon
Editing the package.json file
{
"name": "rate-limiting",
"version": "1.0.0",
"description": "Throttle apis on express",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^16.0.2",
"express": "^4.17.3",
"express-rate-limit": "^6.3.0"
},
"devDependencies": {
"nodemon": "^2.0.19"
}
}
In the above package.json
file, we added start
and dev
scripts, the start script is used for production, whereas the dev script is used for development as it supports hot reload on code change.
Code
Now that the application is configured, let us create the base express application, with express-rate-limit configured. The express-rate-limit
the package is used for achieving throttling, let’s look at how to throttle APIs on express programmatically/ through code.
//* index.js
const express = require("express");
const app = express();
app.use(express.json());
require('dotenv').config();
const PORT = process.env.PORT || 3000;
/*
**** CODE FOR THROTTLING GOES HERE ****
*/
/*
**** THROTTLED AND NORMAL ROUTE GO HERE ****
*/
app.listen(PORT, console.log(`SERVER STARTED ON PORT -> ${PORT}`));
In the above code, we set up the Express server, as a base for the throttling code, and for keeping routes.
Code for throttling
//* CODE FOR THROTTLING
const { rateLimit } = require("express-rate-limit");
const rateLimitOptions = {
windowMs: 60 * 1000, //* kept in miliseconds ...
max: 5, //* Max number of times user is able to hit
message: { message: "Operation failed", data: "rate limit exceeded" },
statusCode: 429,
headers: true,
};
// * provides middleware for rate limiting
let limiter = rateLimit(rateLimitOptions);
In the above code, the rateLimitOptions
is provided as a parameter to the rateLimit()
middleware. The passed options are defined in brief below:
windowMs
: Interval that the user can interact with the APImax
: Defines the number of times that the user can request the API in the givenwindowMs
message
: message to return when the rate limit has exceededstatusCode
: HTTP status code to return when the rate limit has exceededheaders
: Takes in a boolean value, returns rate limit, and remaining values in the header if true is set.
So, that is what is passed into the rateLimit
middleware. The limiter
takes an instance of the rateLimit
middleware. In the above options, the client is able to send max 5 number of requests in a minute. When the limit is reached it returns the message { message: "Operation failed", data: "rate limit exceeded" }
. The status code returned is 429 Too Many Requests
.
Throttled route
app.get("/", limiter, (req, res) => {
res.send("rate limited api");
});
The above route has the throttling middleware implemented in it. It will only take the max
number of requests per given time which is provided in the windowMs
.
Normal Route
app.get("/hello", (req, res) => {
res.send("API without rate limiting");
});
The above code is not throttled so, it can be requested for an unlimited amount of time.
Results
Finally, let’s call the routes through the postman and check the results that are presented through, throttled and non-throttled routes.
Images
Video of throttled API
The above images and video shows that the throttled API can only be hit 5 times before, it throws an error as the limit has exceeded for a minute before it resets. The /hello route which is not throttled/rate limited can be requested at any time and can theoretically, be hit for an unlimited amount of time.
Conclusion
So, in this article, we learned, what throttling and rate limiting is, also how to rate limiting/Throttle APIs on express application through the middleware provided by the package express-rate-limit
.