본문 바로가기

Node.js

Node.js - API 사용량 제한 구현, express-rate-limit (API Limit)

일차적으로 인증된 사용자 (토큰을 발급받은 사용자) 만 API를 사용할 수 있게 필터를 두더라도, 인증된 사용자가 과도한 API 사용을 하게 되면 API 서버에 무리가 갈 수 있다. 따라서 일정 기간 내에 API를 사용할 수 있는 횟수를 제한하여 서버의 트래픽을 줄이는 것이 좋다.  유료 서비스라면 과금 체계별로 횟수에 차이를 둘 수도 있을 것이다.

 

이 기능은 express-rate-limit 패키지로 구현할 수 있다.

 

api 서버의 미들웨어로 다음 기능을 추가해준다.

 

const RateLimit = require('express-rate-limit');

...

exports.apiLimiter = new RateLimit({
    windowMs: 60 * 1000,
    max: 1,
    delayMs: 0,
    handler(req, res) {
        res.status(this.statusCode).json({
            code: this.statusCode, // 기본값 429
            message: '1분에 한 번만 요청할 수 있습니다.'
        });
    }
});

exports.deprecated = (req, res) => {
    res.status(410).json({
        code: 410,
        message: '새로운 버전이 나왔습니다. 새로운 버전을 사용하세요.'
    });
};

 

express-rate-limit으로 apiLimiter 미들웨어를 추가해주었다. 이제 이 미들웨어를 라우터에 넣으면 라우터에 사용량 제한이 걸린다. 미들웨어의 옵션으로는 windowMs (기준 시간), max (허용 횟수), delayMs (호출 간격), handler (제한 초과 시 콜백 함수) 등이 있다. 위 설정은 1분에 최대 한 번 호출 가능하게 되어있으며, 사용량 제한을 초과하면 429 상태 코드와 함께 허용량을 초과했다는 응답을 전송한다.

 

deprecated 미들웨어는 사용하면 안되는 라우터에 붙여줄 것이다. 410 코드와 함께 새로운 버전을 사용하라는 메시지를 응답한다.

 

또한 사용향 제한이 추가되었으므로 기존 API 버전과 호환되지 않는다. 새로운 버전의 API 서비스를 라우터로 만들어주어야 할 것이다.

 

또한 이 경우 서버가 재시작되면 사용량이 초기화된다. 따라서 실제 서비스에선 사용량을 저장할 데이터베이스를 따로 마련하는 것이 좋다. 보통 레디스가 많이 사용된다. 그러나 express-rate-limit 패키지는 데이터베이스와 연결하는 것을 지원하지 않으므로 npm에서 새로운 패키지를 찾아보거나 직접 구현해야 한다.

 

 

출처

Node.js 교과서 개정 2판 - 길벗, 조현영