1.0.2 • Published 11 months ago

rate-limiter-advanced v1.0.2

Weekly downloads
-
License
ISC
Repository
-
Last release
11 months ago

Rate Limiter Package

This package provides middleware for rate limiting in a Node.js application using Redis. It includes two types of rate limiting: one using the rate-limiter-flexible library and a custom implementation.

Installation

To install the package, you need to have Node.js and npm installed. Then run the following command:

npm install rate-limiter-advanced

Usage

Importing the Middleware

Import the middleware functions in your Express.js application:

import { rateLimiterUsingThirdParty, customRedisRateLimiter } from 'rate-limiter-advanced';

Middleware Functions

Rate Limiter Using rate-limiter-flexible

This middleware uses the rate-limiter-flexible library to limit the number of requests a user can make within a specified time window.

export const rateLimiterUsingThirdParty = async (req, res, next) => {
  try {
    await rateLimiter.consume(req.ip);
    return next();
  } catch (error) {
    return res.status(429).jsend.error(`You have exceeded the ${MAX_WINDOW_REQUEST_COUNT} requests in ${WINDOW_SIZE_IN_HOURS} hrs limit!`);
  }
};

Custom Redis Rate Limiter

This middleware implements custom rate limiting logic using Redis to store request logs.

export const customRedisRateLimiter = async (req, res, next) => {
  try {
    const currentRequestTime = moment();
    const record = await getAsync(req.ip);

    if (record == null) {
      const newRecord = [{
        requestTimeStamp: currentRequestTime.unix(),
        requestCount: 1,
      }];
      await setAsync(req.ip, JSON.stringify(newRecord));
      return next();
    }

    const data = JSON.parse(record);
    const windowStartTimestamp = moment().subtract(WINDOW_SIZE_IN_HOURS, 'hours').unix();
    const requestsWithinWindow = data.filter(entry => entry.requestTimeStamp > windowStartTimestamp);
    const totalWindowRequestsCount = requestsWithinWindow.reduce((accumulator, entry) => accumulator + entry.requestCount, 0);

    if (totalWindowRequestsCount >= MAX_WINDOW_REQUEST_COUNT) {
      return res.status(429).jsend.error(`You have exceeded the ${MAX_WINDOW_REQUEST_COUNT} requests in ${WINDOW_SIZE_IN_HOURS} hrs limit!`);
    }

    const lastRequestLog = data[data.length - 1];
    const potentialCurrentWindowIntervalStartTimeStamp = currentRequestTime.subtract(WINDOW_LOG_INTERVAL_IN_HOURS, 'hours').unix();

    if (lastRequestLog.requestTimeStamp > potentialCurrentWindowIntervalStartTimeStamp) {
      lastRequestLog.requestCount++;
      data[data.length - 1] = lastRequestLog;
    } else {
      data.push({
        requestTimeStamp: currentRequestTime.unix(),
        requestCount: 1,
      });
    }

    await setAsync(req.ip, JSON.stringify(data));
    return next();
  } catch (error) {
    return next(error);
  }
};

Applying the Middleware

To use these middleware functions in your Express.js application, apply them to your routes:

import express from 'express';
import { rateLimiterUsingThirdParty, customRedisRateLimiter } from './rateLimiter.js';

const app = express();

app.use('/api', rateLimiterUsingThirdParty);
app.use('/custom-api', customRedisRateLimiter);

app.get('/api', (req, res) => {
  res.send('Rate limited API');
});

app.get('/custom-api', (req, res) => {
  res.send('Custom rate limited API');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

Configuration

The rate limiting configuration is defined by the following constants in the rateLimiter.js file:

  • WINDOW_SIZE_IN_HOURS: The time window size in hours.
  • MAX_WINDOW_REQUEST_COUNT: The maximum number of requests allowed within the time window.
  • WINDOW_LOG_INTERVAL_IN_HOURS: The interval in hours for logging request timestamps.

Dependencies

  • rate-limiter-flexible: Flexible and efficient rate limiter for Node.js.
  • moment: A library for parsing, validating, manipulating, and formatting dates.
  • redis: A Redis client for Node.js.
  • jsend: A library for JSend-compliant response formatting.
  • util: Node.js utility module for promisifying functions.

License

This package is licensed under the ISC License.

1.0.2

11 months ago

1.0.1

11 months ago

1.0.0

11 months ago