전적 검색 / 갱신 로직
현재 소환사 전적 검색 / 갱신은 여러 riot api를 통해 값을 가져온다.
- 소환사 이름으로 소환사의 개인 정보(summonerId, puuid,…)를 가져온다.
- 소환사의 summonerId로 소환사의 전적(win, tier, level, lp…)을 가져온다.
- 소환사의 summmonerId로 소환사의 모스트 챔피언을 가져온다.
- 소환사의 puuid로 플레이한 경기의 id인 matchId 10개를 가져온다.
- 소환사의 matchId로 게임 내 상세 데이터를 가져온다.
여기서 4번이 10개를 가져오면 반복문을 통해 게임내 데이터를 가져온다.
그러므로 소환사 검색 / 갱신은 riot api에 요청하는 양은 14번 정도이다.
그리고 riot에서는 api 요청 제한이 걸려있고 한번 제한이 걸리면 1 , 2분간 riot api를 사용하지 못하게 된다.
그래서 한번 소환사 전적 갱신한 소환사에 대해서는 약 5분의 텀을 두어 과도한 api 요청을 막는게 목적이다.
해결
NestJs 에서는 인터셉터를 통해 http 요청의 처리를 컨트롤러가 실행 전/ 실행 후에 요청 값을 수정 할 수 있다.
그래서 전적갱신의 요청 파라미터 값을 인터셉터에서 먼저 필터링 하는 로직을 구현하였다.
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class ThrottleInterceptor implements NestInterceptor {
private readonly cache = new Map<string, number>();
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest();
const summonerName = request.params.summonerName;
const requestTime = Date.now();
if (this.cache.has(summonerName)) {
const lastRequestTime = this.cache.get(summonerName);
if (requestTime - lastRequestTime < 5 * 60 * 1000) {
throw new HttpException('Too many requests', HttpStatus.TOO_MANY_REQUESTS);
}
}
this.cache.set(summonerName, requestTime);
return next.handle();
}
}
인터셉터의 필드를 Map 자료구조로 키(소환사 이름) , 값(요청 시간)으로 지정하였다.
그리고 요청이 오면 해당 필드에서 소환사를 찾고 요청 시간이 5분 미만이면 429에러를 뱉는다.
테스트
it("/GET 소환사 전적 갱신 특정 소환사 갱신 후 해당 소환사 5분 안에 다시 요청시 error?", async () => {
const summonerName = encodeURIComponent("쿠바버샷추가");
await request(app.getHttpServer()).get(`/summoner/refresh/${summonerName}`);
const response = await request(app.getHttpServer()).get(
`/summoner/refresh/${summonerName}`
);
expect(response.statusCode).toBe(429);
expect(response.body.message).toEqual("Too many requests");
});
같은 소환사를 2번 전적 갱신을 할 경우 정상적으로 429 코드와 에러메세지가 발생한다.
e2e테스트를 통해 확실하게 api를 검증 할 수 있다.
'Project > Carryduo' 카테고리의 다른 글
Carryduo 정적 파일 저장 및 응답하기 (0) | 2023.03.22 |
---|---|
RDS start/stop 으로 실행 시간 조작하기 (0) | 2023.03.22 |
Carryduo 테스트코드 (0) | 2023.03.21 |
Carryduo DTO (0) | 2023.03.21 |
데이터 수집 프로세스 관리 및 오프셋 파일 저장 (0) | 2023.03.21 |