SHOOT - API 요청 횟수 제한

민경찬·2023년 2월 11일
0

백엔드

목록 보기
2/19
post-thumbnail

서론


프론트엔드에서 무한 스크롤 개발 도중 한 번에 많은 양의 요청을 던졌고 서버에서는 DB 커넥션 수 제한이라는 에러가 발생했다.

한 명의 사용자로부터 너무 반복적인 요청이 오는 것을 어떻게 예외처리 해줘야하는지 알아보자.


본론


1. express-rate-limit 사용

npm i express-rate-limit

express-rate-limit 라이브러리를 다운로드 받아준다.

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

module.exports = rateLimit({
    windowMs: 60 * 1000,
    max: 3,
    handler(req, res) {
        res.status(423).send({
            message : 'too many request'
        });
    },
})

우선 테스트를 위해 분당 3번의 요청만 할 수 있도록 설정한다.

postman에서 빠르게 세 번의 요청을 넣어주면
잘 나온다.

이제 10초에 10개의 api를 요청할 수 있도록 셋팅하고 마무리!

2. 게시글 업로드 쿨타임 설정

같은 유저가 같은 제목의 게시글을 1분 내로 연속적으로 올릴 수 없도록 하는 코드를 만들어 보려고 한다.

postCoolDown.js

const redis = require('redis').createClient();

module.exports = (req, res, next) => {
    (async () => {
        const title = req.body.title || '';
        const loginUserEmail = req.email || '';
        
        try{
            await redis.connect();

            const existState = await redis.exists(`post_upload_${loginUserEmail}_${title}`);
            if(existState){
                await redis.disconnect();

                res.status(423).send({
                    message : 'too many request'
                });
            }else{
                await redis.set(`post_upload_${loginUserEmail}_${title}`, 1);
                await redis.expire(`post_upload_${loginUserEmail}_${title}`, 60); // 1 minutes

                await redis.disconnect();

                next();
            }
        }catch(err){
            console.log(err);

            if(redis.isOpen){
                await redis.disconnect();
            }
            
            res.status(409).send({
                message : 'unexpected error occured'
            });
        }
    })();
}

redis에 업로드 유저 이름과 게시글 제목을 올리고 만료시간을 1분으로 설정한다. 미들웨어로 등록해준 다음에 바로 테스트 해보자.

1분 안에 같은 제목의 게시글을 넣으려고 하면 잘 막힌다. 역시 재밌다...

추가 고려 사항 : redis에 key값으로 넣을 수 있는 string길이는 제한되어 있다. 그래서 key로 넣을 문자열의 최대 길이를 먼저 파악해야한다.


결론


사용법이 하나도 안 어려웠다. 특히 express-rate-limit는 적극적으로 사용하도록 하자.




참고

0개의 댓글