DEV Community

Zihadul Islam
Zihadul Islam

Posted on

Node js api rate limit

Here we learn How node js api rate limiting
First you need to install npm i ioredis this package

COnfigure redis client

const Redis = require('ioredis');
const redis = new Redis(); // You might need to configure this properly

async function incr(key) {
  return await redis.incr(key);
}

async function expire(key, seconds) {
  return await redis.expire(key, seconds);
}

async function ttl(key) {
  return await redis.ttl(key);
}

module.exports = {
  incr,
  expire,
  ttl
};
Enter fullscreen mode Exit fullscreen mode

Make a generic rate limiter function

const redis = require('./redis-client');
function rateLimiter = ({secondWindow, allowdHits}) {
    return  async function (req, res, next) {
        // we use client ip as redis key here

        const ip = req.headers['x-forworded-for'] || 
         req.connection.remoteAddress || req.ip
        // if you use express use `req.ip` to get client ip

        const requests = await redis.incr(ip);
        let ttl;
        if(requests === 1) {
           await redis.expire(ip, secondWindow);
           ttl = secondWindow;
        }else {
              ttl = await redis.ttl(ip);
        }
        if(requests > allowdHits) {
           return res.status(503).json({
                response: 'error',
                callsInMinute: requests,
                ttl
           })
        } else {
               req.requests = requests;
               req.ttl = ttl;
               next();
         }
    }
}
Enter fullscreen mode Exit fullscreen mode

How to use it.

app.post('/api/login', rateLimiter({secondWindow: 5, 
    allowdHits: 3}), async(req, res) => {
    return res.json({
        response: 'ok',
        callsInMinute: req.requests,
        ttl: req.ttl
    })
})

app.post('/api/checkout', rateLimiter({secondWindow: 12, 
    allowdHits: 7}), async(req, res) => {
    return res.json({
        response: 'ok',
        callsInMinute: req.requests,
        ttl: req.ttl
    })
})
Enter fullscreen mode Exit fullscreen mode

Top comments (0)