캐리듀오 소환사 능력치 갱신 기간 제한 구현

통계 검색/업데이트 로직

현재 소환사 통계 검색/새로고침은 여러 Riot API를 통해 값을 가져옵니다.

  1. 소환사의 개인 정보(summonerId, puuid, …)를 소환사 이름으로 가져옵니다.
  2. 소환사의 ID로 소환사의 기록(Gain, Tier, Level, Lp…)을 가져옵니다.
  3. 소환사의 summmonerId로 소환사의 가장 위대한 챔피언을 얻으십시오.
  4. 소환사의 Puuid와 플레이한 매치 ID인 MatchId 10개를 가져옵니다.
  5. 소환사의 matchId로 자세한 게임 내 데이터를 가져옵니다.

여기서 숫자 4가 10이 되면 게임 데이터가 루프됩니다.

그 결과 Riot API에 서머너 검색/업데이트 요청이 약 14회 정도 이루어집니다.

그리고 Riot에는 API 요청에 대한 제한이 있으며 제한이 설정되면 1~2분 동안 Riot API를 사용할 수 없습니다.

따라서 소환사 기록이 업데이트되면 소환사에게 5분 간격을 설정하여 과도한 API 요청을 방지하는 것이 목적입니다.

해결하다

NestJ에서는 컨트롤러가 인터셉터의 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();
  }
}

인터셉터의 필드는 카드 데이터 구조로 키(소환사 이름)와 값(요청 시간)이라고 합니다.

그리고 요청이 오면 해당 필드에서 소환사를 찾아주고, 요청 시간이 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");
});


동일한 소환사를 두 번 업데이트하면 일반적으로 429 코드와 오류 메시지가 나타납니다.

e2e 테스트를 통해 확실하게 API를 확인할 수 있습니다.