스파르타 이노캠/본과정

2023. 07. 24 월 - riot API 사용해보기

haema_ 2023. 7. 24. 23:50
728x90

현재는 op.gg를 클로닝하는 프로젝트 진행중이다.

 

앞에서의 WIL에서도 살짝 언급했지만, riot API를 사용해서 op.gg처럼 정보를 뿌려주는 것이 생각보다 험난했다.

.https://news.op.gg/news/5565978/%27%EB%A6%AC%EA%B7%B8-%EC%98%A4%EB%B8%8C-%EB%A0%88%EC%A0%84%EB%93%9C%27-%EA%B2%8C%EC%9E%84-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%B3%B4%EB%8A%94

 

'리그 오브 레전드' 게임 데이터는 어떻게 보는 걸까?

롤 전적, 모든 게임의 전적, 챔프 평점, KDA, 승률을 볼 수 있고 리플을 보거나 자신의 게임을 녹화를 할 수 있습니다. 지금 바로 당신의 소환사명을 검색해보세요!

news.op.gg

불러오는 로직 자체는 op.gg에서 순서와 예시까지 보여주면서 상세하게 설명해주고 있다.

그런데 이걸 실제로 서버 안에서 해당 url로 요청을 보내고, 저 긴 json data를 파싱해서 원하는 데이터로 쓰기 까지 많은 어려움이 있었다.

 

 

1. 소환사 스펠 정보.

Riot api요청에서 소환사 스펠 정보를 비롯한 아이템 정보, 룬 정보 등은 int값으로 나타낸다. 소환사 스펠의 경우summoner1Id와 summoner2Id 라는 이름으로 int값으로 보내주고 있다. 나는 리그 오브 레전드라는 게임의 구성에 매우 익숙했기에 저 key명을 보고도 찾는 데에 그리 어려움은 없었다. summoner라는 이름을 포함한 2개의 값은 소환사 스펠일 것이라고 쉽게 예측했기 때문이다.

하지만 그냥 summoner1Id, summoner2Id라는 이름만 가지고는 그게 소환사 스펠인지 명확하게 나타내지는 않는다고 느껴졌다. 또 apis 페이지에서 각 key값에 대한 description은 대부분 비어있는 상태였기 때문에, 만약 key이름만으로는 파악하기 힘든 정보가 있으면 어떤 게 내가 원하는 값인지를 찾기가 힘들 것 같았다.

 그리고 이미지와 매핑될 만한 정보들이 int값으로 보내져서, 해당 int값이 어떤 것과 매핑되는지 정확하게 파악하기가 힘들었다.

 

해결책으로는 op.gg 의 소스를 뜯어보면서,op.gg의 해당 페이지에서 실제로 출력해주는 item, rune, spell, champion사진 등의 소스를 확인해본 결과, item과 rune의 경우 받아오는 int값 자체를 키값으로 static에서 뽑아오고 있는 것을 확인할 수 있었다. ex) 3678.png

champion 이미지의 경우 챔피언의 이름으로 이미지를 구분하고 있었지만, 다행히 api 정보 중 championName이 String형식으로 들어가 있어서 해당 값을 response에 추가해주었다. ex) Neeko.png

 

문제는 spell정보였는데 spell의 경우에는 데이터 값이 int밖에 없었지만, 실제로 op.gg에서 매핑하는 이미지 파일의 이름은 SummonerBoost, SummonerFlash와 같은 스펠의 이름이었다. 공식 문서 등에서 해당 관련 정보를 찾는 데에 실패해서, 결국 op.gg로 검색해서 매핑되는 스펠 사진과 api요청으로 나온 summoner1Id, summoner2Id 를 비교해가면서 데이터를 직접 수집했다.

 

데이터 수집이 완료된 후 서버 측에서 사진과 맞는 spellName을 매핑해주어야했는데, int값이 1~25정도의 작은 값이였어서 처음엔 enum을 사용해서 해당 int값을 순서로 사용해서 매핑을 시도했다.

그런데 스펠값을 보다 보니 방어막은 21인데 그 바로 아래 있는 점화는 14인 등 중간 중간 비는 값이 많았다. 그런데 순서는 지켜야 하니 비는 값들을 blank처리로 채워넣는 경우가 너무 많아서, 오히려 비효율적이라고 느껴졌다. 결국 switch문으로 각 int값을 case로 변환해주는 메서드를 하나 추가함으로써 해결했다.

다만 라이엇의 패치 방향성과 관련해서 만약 사용가능한 스펠이 생겼다가 없어지는 일이 잦은 경우라면, enum으로 정의해 놓고 정의는 되어있지만 현재는 안쓰는 값들도 미리 넣어놓는 것도 고려해볼만 할 것 같다.

 

 

2. 통계

op.gg와 같은 전적검색 사이트가 대단하다고 느꼈던 부분이다. product key에서 요청할 수 있는 data풀이 더 넓은 지는 모르지만, 개인이 활용할 수 있는 키 수준으로는 20게임 통계라던지, 특정 시즌 랭크 전적 등을 조회하기가 힘들었다.

그래서 시즌 랭크 정보같은 부분은 포기하고, 최근 전적 조회에 집중하기로 결정했다.

op.gg의 전적 검색 페이지와 비슷한 화면을 띄우기 위해서는 매우 방대한 양의 정보가 필요했는데, 이를 최대한 가공해서 클라이언트가 원하는 값만을 받아서 최대한 바로 쓰게끔 만들고 싶었다.

위와 같이 표시된다고 했을 때, 눌러서 더 상세한 조회를 하는 기능은 시간 여건 상 포기했다.

 

이 화면을 띄우기 위해서 MatchId를 기준으로 상세조회를 할 경우 저 10명의 소환사정보들이 수백 줄의 길이로 각각 전부 들어가기 때문에 상세조회 기능이 없는 우리의 경우 불필요한 데이터가 너무 많이 발생하게 된다.

 

기존에 restTemplate에서 요청을 보낼 때부터 mapping을 조건에 따라 구성하고 싶었지만, 직접 구현해내는 데에는 실패했다.

 

해결책으로는 일단 모든 정보를 받아온 뒤에, 검색에 활용된 puuid를 바탕으로 participants list에서 puuid를 체크 한 후, 일치하지 않는 값들은 소환사네임, 챔피언정보와 같이 꼭 필요한 최소한의 정보로 재생성해서 교체해주었다.

 

각각의 매치가 조회되고 그 매치가 쌓여가는 과정에서 최근 n게임에 대한 통계도 낼 수 있을 것 같아서, 소환사 정보를 매핑해줄 때 검색된 유저가 플레이한 챔피언과, k/d/a, 승패 count를 담는 Dto를 하나 추가로 생성해서 누적해준 후 response에 같이 반환해주었다.

 

단순 api 요청만으로는 전혀 찾아볼 수 없는 통계들

 

이 과정에서 해당 stream의 길이가 매우 길어져서, 추후 리팩토링을 시도해보아야 겠다는 생각도 들었다.

 

 


아직 프로젝트가 끝나지는 않았지만, open API의 데이터를 다루어보면서 느낀 점은

1. 누가 보더라도 명확한 이름을 짓는 것이 매우 중요하다.

2. 부득이하게 이해가 어려울 만한 부분을 만들어야 한다면 description을 이용하자.

3. Mapping후 사용해야 하는 정보가 있다면, 해당 정보에 대한 mapping 테이블을 만들어서 같이 제공하자.

 

정도인 것 같다.

 

이번 프로젝트에서는 나름 프론트엔드의 고충 중 한 가지를 간접 체험한 것 같다.

무분별하게 뿌려지는 데이터들은 받아들이는 입장에서는 지옥과 같다.


이후 고려해 볼 만한 점.

 

op.gg의 상세조회 로직은

1. SummonerName 조회 -> puuid 찾아내기

2. 찾은 puuid 로 해당 유저가 참여한 게임의 id List를 n개 찾아내기 ex) ["KR-148294358", "KR-1239123922",...]

3. 각 MatchId를 상세 조회. (n개만큼 요청 발생)

와 같은 구성이다.

 

내가 활용 가능한 개인 key의 요청 한계를 생각해볼 때, 어느 정도 최적화가 필요한 부분이 있다.

 

물론 제일 부하가 큰 것은 각 Match를 상세조회하는 부분이지만, 조금이나마 최적화 시킬 만한 방법으로 SummonerName마다 고유한 puuid값을 개인 db에 저장해놓고 db에 존재할 경우 1번 요청을 생략하는 것이다.

 

 

그렇게 구성했을때의 문제점은

 

1.상세조회 페이지에서 레벨, 소환사 아이콘의 변동이 있어야 할 때 조회 후 업데이트가 불가능하다는 점이다.

-> 관련한 해결책으로는 레벨과 소환사아이콘 정보까지 db에 같이 넣어놓고, 조회가 드문 시간대에 정기적으로 요청을 날려서 db를 업데이트 하는 방법이 있을 것 같다.

 

2. 소환사 닉네임이 변경될 경우, DB에 사용되지 않는 값이 생긴다. 또 추후 그 닉네임을 다른 사람이 사용할 경우, 기존의 puuid로 조회될 가능성이 있다.

-> 마찬가지로 정기적인 업데이트를 통해 소환사 닉네임이 조회되지 않을 경우 db를 삭제하거나, puuid matching을 통해 다를 경우 업데이트 하는 방식으로 방지할 수 있을 듯하다.

 

 

그리고 무엇보다도 이미 조회된 유저의 데이터를 캐싱해서 결과값이 동일할 것으로 판단되는 요청에 대해서는 다시 Riot API요청이 나가지 않는 방법을 구현해야 할 것 같다.

반응형