๐Ÿšจ RIOT API๋ฅผ ์ด์šฉํ•ด์„œ ๋กค ์ „์  ๊ฒ€์ƒ‰ ์‚ฌ์ดํŠธ ๋งŒ๋“ค๊ธฐ (2) - RIOT API ํŒŒ์‹ฑํ•˜๊ธฐ

junhok82ยท2020๋…„ 6์›” 3์ผ
1

์ด๋ฒˆ ํฌ์ŠคํŠธ๋Š” ํ”„๋กœ์ ํŠธ ์ฒซ๋ฒˆ์งธ ์ด์Šˆ Riot API ์Šน์ธ ๋ฐ ํŒŒ์‹ฑ์—์„œ ๋‘๋ฒˆ์งธ ํ•ญ๋ชฉ, Riot API ํŒŒ์‹ฑํ•˜๊ธฐ๋‹ค. ๋‚˜๋Š” ๊ฐœ๋ฐœ๋ถ€๋ถ„์ด ์•„๋‹Œ๊ณผ์ • ์ค‘ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•ด์•ผํ•˜๋Š” ๋ถ€๋ถ„์„ Preparations๋กœ ๊ตฌ๋ถ„ํ•˜๊ณ ์žˆ๋‹ค.


์œ ๋ช…ํ•œ ๋ฆฌ๊ทธ์˜ค๋ธŒ๋ ˆ์ „๋“œ ์ „์  ์‚ฌ์ดํŠธ๋ฅผ ํด๋ก ์ฝ”๋”ฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค. ํ˜ผ์ž์„œ ์ง„ํ–‰ํ•˜๋Š”๋งŒํผ 1์ฐจ์ ์ธ ๋ชฉํ‘œ๋Š” ๊ฐ„๋‹จํžˆ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ณผ์ •์„ ๊ฑฐ์น˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

  • โœ”๏ธ Riot API๋ฅผ ์ธ์ฆ
  • ๐Ÿ”› Jackson์„ ์ด์šฉํ•ด์„œ Riot API ๋ฐ์ดํ„ฐ ํŒŒ์‹ฑ
  • AWS RDS๋กœ DB ์„ค๊ณ„ ๋ฐ ๊ตฌ์ถ•
  • Spring Boot๋ฅผ ์ด์šฉํ•ด์„œ MVC ๊ตฌ์กฐ ๋งŒ๋“ค๊ธฐ (with mybatis)
  • Vue๋ฅผ ์ด์šฉํ•ด์„œ ํ”„๋ก ํŠธ๋ฅผ ๊ตฌ์ถ•
  • EC2๋กœ ๋ฐฐํฌ

๐Ÿšจ RESTFUL Project ๐Ÿšจ โ‡ข RIOT API + Spring Boot + AWS EC2 & RDS


์ฑ„ํƒํ•œ ํŒŒ์‹ฑ ๋ฐฉ๋ฒ•

๋‚˜๋Š” Spring Boot๋ฅผ ์ด์šฉํ•ด์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰์ค‘์ด๋‹ค. ๋งˆ์นจ ์ด ํ”„๋ ˆ์ž„์›Œํฌ์—๋Š” Jackson ์ด๋ผ๋Š” ํ›Œ๋ฅญํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์กด์žฌํ•œ๋‹ค. Jackson์€ java๋ฅผ json์œผ๋กœ json์„ java๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ Riot์œผ๋กœ๋ถ€ํ„ฐ ์–ป์–ด์˜จ json์„ ์ž๋ฐ” DTO์— ๋Œ€์ž…์‹œ์ผœ์ฃผ๋Š” ๋ฐฉ์‹์„ ์ฑ„ํƒํ–ˆ๋‹ค.

๋ผ์ด์—‡์œผ๋กœ๋ถ€ํ„ฐ json ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

์•ž์„œ APIํ‚ค๋ฅผ ์ธ์ฆํ•ด์„œ ๋ฐ›์•˜๋‹ค๋ฉด ๋”์šฑ ์ข‹์ง€๋งŒ, ๊ตณ์ด ๋ฐ›์ง€ ์•Š์•˜์–ด๋„ DEVELOPMENT API KEY๋ฅผ ์ด์šฉํ•ด์„œ ์ž„์‹œ์ ์œผ๋กœ ํŒŒ์‹ฑํ•˜๊ฑฐ๋‚˜ ๋ผ์ด์—‡ API์—์„œ ํ…Œ์ŠคํŠธ ํ• ์ˆ˜์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์†Œํ™˜์‚ฌ ์ •๋ณด๋ฅผ ๋‹ด๊ณ ์žˆ๋Š” json ๋ฐ์ดํ„ฐ๋ฅผ ๋ผ์ด์—‡ API์—์„œ ํ…Œ์ŠคํŠธํ•ด๋ณด์ž. SUMMONER์ด๋ผ๋Š” API๊ฐ€ ์†Œํ™˜์‚ฌ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ ์žˆ๋‹ค. ํƒญ์„ ๋ˆŒ๋Ÿฌ์„œ ๋ณด๊ฒŒ๋˜๋ฉด, ๋‹ค์Œ๊ณผ๊ฐ™์ด 4๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ๋‚˜์˜จ๋‹ค.

์˜ค๋ฅธ์ชฝ ํŒŒ๋ž€์ƒ‰ ๊ธ€์”จ๋ฅผ ์ž์„ธํžˆ๋ณด๋ฉด 4๊ฐ€์ง€ ๋ชจ๋‘ summoner๋ฅผ ๊ฐ€์ ธ์˜ฌ์ˆ˜์žˆ๋‹ค. ๋‹ค๋งŒ ๋ชจ๋‘ ๋ฐฉ๋ฒ•์ด ๋‹ค๋ฅธ๋ฐ, ๊ทธ์ค‘ ์†Œํ™˜์‚ฌ ์ด๋ฆ„์œผ๋กœ ๊ฒ€์ƒ‰ํ•˜๋Š” 2๋ฒˆ์งธ ํƒญ์„ ์„ ํƒํ–ˆ๋‹ค. ํด๋ฆญํ•˜๊ฒŒ๋˜๋ฉด DTO๋ถ€ํ„ฐ ๋ฐฉ๋ฒ•๊นŒ์ง€ ๊ต‰์žฅํžˆ ์ž์„ธํžˆ ์†Œ๊ฐœํ•ด์ฃผ๊ณ ์žˆ๋‹ค. ํ…Œ์ŠคํŠธํ•˜๊ธฐ์œ„ํ•ด์„œ๋Š” ๋‹จ์ˆœํžˆ ์†Œํ™˜์‚ฌ๋ช…์„ ์ ๊ณ  DEVELOPMENT API KEY๋ฅผ ํ†ตํ•ด ์š”์ฒญ(REQUEST)๋ฅผ ๋ณด๋‚ด๊ฒŒ๋˜๋ฉด ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

๋‚˜๋Š” ๊ฐ“ ํŽ˜์ด์ปค์„ฑ๋‹˜์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์š”์ฒญํ•ด๋ณด์•˜๋‹ค. ์š”์ฒญ์„ ํ•˜๋ฉด REQUEST URL๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ RESPONSE BODY๊นŒ์ง€ ์ •๋ณด๋“ค์ด ์ญ‰๋‚˜์˜จ๋‹ค. ์ด๋•Œ ๋ˆˆ์—ฌ๊ฒจ ๋ด์•ผํ• ๋ถ€๋ถ„์€ ์„ธ๊ฐ€์ง€๋‹ค.

  1. REQUEST URL
    : GET๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋Š” URL๋กœ ๋‚˜์ค‘์— ์ง์ ‘ ํŒŒ์‹ฑํ•  ๋•Œ ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ์šฐ๋ฆฌ๊ฐ€ ๋„ฃ์–ด์ค˜์•ผํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ์†Œํ™˜์‚ฌ๋ช…๊ณผ API_KEY๊ฐ€ ํ•„์š”ํ–ˆ๋‹ค. ์ฐธ๊ณ ๋กœ API_KEY๋Š” ํ•ญ์ƒ ํ•„์š”ํ•˜๋‹ค.

  2. RESPONSE CODE
    : ์ƒํƒœ์ฝ”๋“œ๋Š” ๋‹น์—ฐํžˆ ๊ธฐ๋ณธ์ค‘์— ๊ธฐ๋ณธ์ด๋‹ค. ๋ผ์ด์—‡ DOCS์—์„œ๋„ ์ƒํƒœ์ฝ”๋“œ๋ฅผ ์ž์„ธํžˆ ์„ค๋ช…ํ•ด์ฃผ๊ณ ์žˆ๋‹ค. ์‹ค์ œ๋กœ ํŒŒ์‹ฑํ•˜๋‹ค๊ฐ€ ์—ฌ๋Ÿฌ๋ฒˆ ์˜ค๋ฅ˜๊ฐ€ ๋‚ฌ์—ˆ๋Š”๋ฐ, ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ๊ธˆ๋ฐฉ ๋น ์ ธ๋‚˜์˜ฌ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

  3. RESPONSE BODY
    : ๋งˆ์ง€๋ง‰์œผ๋กœ, ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ด๊ธด ์‘๋‹ต ๊ฒฐ๊ณผ๋‹ค. ์ด๋Ÿฐ ๋ฐ์ดํ„ฐ๋“ค๋กœ ์—ฌ๋Ÿฌ API๋ฅผ ํŒŒ์‹ฑํ•ด์„œ ์„œ๋กœ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ํŒŒ์•…ํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•˜๋Š”๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€๋Š” ํ…Œ์ŠคํŠธ์˜€๊ณ , Apache์—์„œ ์ œ๊ณตํ•˜๊ณ  ์žˆ๋Š” HttpClient ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์„œ ๋ฐ›์•„์™”๋‹ค. ๋จผ์ € ์ •๋ณด๊ฐ€ ๋“ค์–ด๊ฐˆ ๊ฐ์ฒด๋ฅผ์œ„ํ•ด DTO(Data Transfer Object)๋ฅผ ๋งŒ๋“ค์–ด ์คฌ๋‹ค. ์•ž์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณธ์‚ฌ๋žŒ์ด๋ผ๋ฉด ์•Œ์žˆ๊ฒ ์ง€๋งŒ, ๋ผ์ด์—‡์—์„œ DTO์ •๋ณด๋„ ์นœ์ ˆํ•˜๊ฒŒ ์•Œ๋ ค์ฃผ๊ณ ์žˆ๋‹ค.

ํด๋ž˜์Šค๋ช…๊นŒ์ง€ ์ œ์•ˆํ•ด์ฃผ๋Š” ๊ฐ“..

๋‚˜๋Š” MVC๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ• ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ ์ ˆํ•œ ํŒจํ‚ค์ง€์— ์ƒ์„ฑํ•ด๋‘์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Key๋‹ด๊ณ ์žˆ๋Š” Static ๋ณ€์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค๊ณ , API_KEY๋ฅผ ๋‹ด์•„๋†จ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋•Œ ๊นƒ์—์˜ฌ๋ฆฐ๋‹ค๋ฉด gitignore๋ฅผ ํ•ด์ค˜์•ผํ•œ๋‹ค๋Š”์ ์„ ์žŠ์ง€๋ง์ž.

// ๊ณต๋ฐฑ ์ฒ˜๋ฆฌ
String SummonerName = name.replaceAll(" ", "%20");		
String requestURL = "https://kr.api.riotgames.com/lol/summoner/v4/summoners/by-name/"+ SummonerName + "?api_key=" + Key.API_KEY;
		
try {
	HttpClient client = HttpClientBuilder.create().build(); // HttpClient ์ƒ์„ฑ
	HttpGet getRequest = new HttpGet(requestURL); //GET ๋ฉ”์†Œ๋“œ URL ์ƒ์„ฑ
	HttpResponse response = client.execute(getRequest);
	
	//Response ์ถœ๋ ฅ
	if (response.getStatusLine().getStatusCode() == 200) {
		ResponseHandler<String> handler = new BasicResponseHandler();
		String body = handler.handleResponse(response);
        
        }
        ...

์ด๋Ÿฐ์‹์œผ๋กœ json ๋ฐ์ดํ„ฐ๋ฅผ response body์— ๋‹ด์•˜๋‹ค. ์ฒ˜์Œ postman์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋Š”๋ฐ ์ž๊พธ ๋ฐ์ดํ„ฐ๊ฐ€ ์•ˆ๋„˜์–ด์™€์„œ ๊ณ ์ƒํ–ˆ๋‹ค. ๋ฌธ๋“ ๋ผ์ด์—‡ API์—์„œ ํ…Œ์ŠคํŠธํ• ๋•Œ ๊ณต๋ฐฑ์ฒ˜๋ฆฌ๊ฐ€ %20์œผ๋กœ ๋˜์–ด์žˆ์—ˆ๋‹ค๋Š”๊ฒƒ์„ ๋ดค๋˜์ง€๋ผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

name์€ controller๋กœ๋ถ€ํ„ฐ @Pathvariable ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜์–ด์˜ค๋Š” ์†Œํ™˜์‚ฌ๋ช…์ด๋‹ค. ์ดํ›„๋Š” HttpClient๋ฅผ ํ†ตํ•ด์„œ response๋ฅผ ๋ฐ›์•„๋‚ด๊ณ ์žˆ๋‹ค. ๋‹ค๋งŒ ์ƒํƒœ์ฝ”๋“œ๊ฐ€ 200์ผ๋•Œ์™€ ๊ทธ ์ด์™ธ์ผ๋•Œ๋Š” ๊ตฌ๋ถ„ํ•ด์„œ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ์—ˆ๋‹ค.

Jackson์„ ์ด์šฉํ•ด์„œ json response๋ฅผ java๋กœ ๋ฐ”๊พธ๊ธฐ

์œ„์—์„œ ๊ตฌํ•œ Response body๋ฅผ ์ถœ๋ ฅํ•ด๋ณด๋ฉด ๊ต‰์žฅํžˆ ๊ธด jsonํ˜•์‹์˜ ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ๋œ๋‹ค. Jackson์„ ์ด์šฉํ•˜๋ฉด ์•„์ฃผ ๊ฐ„ํŽธํ•˜๊ฒŒ java ๊ฐ์ฒด๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

ObjectMapper objectMapper = new ObjectMapper();
Summoner summoner = null;	// DTO

// ๊ณต๋ฐฑ ์ฒ˜๋ฆฌ
String SummonerName = name.replaceAll(" ", "%20");
String requestURL = "https://kr.api.riotgames.com/lol/summoner/v4/summoners/by-name/"+ SummonerName + "?api_key=" + Key.API_KEY;
		
try {
	HttpClient client = HttpClientBuilder.create().build(); // HttpClient ์ƒ์„ฑ
	HttpGet getRequest = new HttpGet(requestURL); //GET ๋ฉ”์†Œ๋“œ URL ์ƒ์„ฑ
	HttpResponse response = client.execute(getRequest);
	
	//Response ์ถœ๋ ฅ
	if (response.getStatusLine().getStatusCode() == 200) {
		ResponseHandler<String> handler = new BasicResponseHandler();
		String body = handler.handleResponse(response);
        	summoner = objectMapper.readValue(body, Summoner.class);   // String to Object๋กœ ๋ณ€ํ™˜
        
        }
        ...

์œ„์—์„œ ๋‚˜์˜จ ์ฝ”๋“œ์™€ ๋น„๊ตํ•ด์„œ 3์ค„๋งŒ ๋ฐ”๋€Œ์˜€๋Š”๋ฐ, jsonํ˜•ํƒœ์˜ String์„ DTO ๊ฐ์ฒด๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

๋‚ด๊ฐ€ ํŒŒ์‹ฑํ•œ ๋ฐ์ดํ„ฐ

๋ผ์ด์—‡ API์—์„œ ํ…Œ์ŠคํŠธํ•˜๋ฉด์„œ ๋Š๋ผ์…จ๊ฒ ์ง€๋งŒ, ์–ด๋–ค๋ฐ์ดํ„ฐ๋“ค์ด ์žˆ๋Š”์ง€ ์ง์ ‘ ํ™•์ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๋‚˜๋„ ์‚ฝ์งˆ(?)์„ ํ•ด๊ฐ€๋ฉฐ ๋‚˜๋ฆ„ ์„ ์ •์„ ํ•ด๋ดค๋‹ค. '์•ž์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋Š”๋ฐ ํ•„์š”ํ• ์ˆ˜๋„ ์žˆ๊ฒ ๋‹ค'๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค๋ฉด ์ผ๋‹จ ํŒŒ์‹ฑ์„ ํ•ด์™”๋˜ ๊ฒƒ๊ฐ™๋‹ค.

  1. Summoner ย ย ย ย ย ย ย ย ย ย  ย ย ย  : ์†Œํ™˜์‚ฌ ์ •๋ณด
  2. Spectator ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย : ์†Œํ™˜์‚ฌ ํ˜„์žฌ ๊ฒŒ์ž„ ์ •๋ณด
  3. MatchList ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย : ์†Œํ™˜์‚ฌ ์ „์  ๋ฆฌ์ŠคํŠธ
  4. Champion ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย : ์ฑ”ํ”ผ์–ธ ๋กœํ…Œ์ด์…˜ ์ •๋ณด
  5. Champion-mastery : ์†Œํ™˜์‚ฌ๋งˆ๋‹ค ์ฑ”ํ”ผ์–ธ ์ˆ™๋ จ๋„ ์ •๋ณด

ํ•œ๋ฒˆ ์ƒ๊ฐํ•ด๋ด์•ผ ํ–ˆ๋˜ ๊ฒƒ

๋‚ด๊ฐ€ ์ฑ„ํƒํ•œ ํŒŒ์‹ฑ ๋ฐฉ๋ฒ•์€ response body ๋‚ด์šฉ ๋ชจ๋“ ๊ฒƒ์„ ํ•˜๋‚˜์˜ ๋ฌธ์ž์—ด์— ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— List์— ๋‹ด์•„์•ผํ•˜๋Š” ๊ฒƒ๋“ค์€ ์ •๊ทœํ™”์ž‘์—…์ด ํ•„์š”ํ–ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ๋‹ค๋ฅธ ํŒŒ์‹ฑ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ดค์—ˆ๋Š”๋ฐ, ์ƒ๊ฐํ•ด๋ณด๋‹ˆ ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ๋ฉด๋˜๋Š” ๋ถ€๋ถ„์ด์—ˆ๋‹ค. ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ฌธ์ œ๋ฅผ ๋ฌธ์ œ๋กœ๋งŒ ํ‘ธ๋‹ˆ, ์ด๋Ÿฐ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์กฐ์ฐจ ๋Œ์•„๊ฐ€๋ คํ–ˆ๋˜ ๋‚ด ๋ชจ์Šต์„ ๋ณด์•˜๋‹ค. ํ•œ๋ฒˆ ์ƒ๊ฐํ•ด๋ด์•ผ ํ–ˆ๋˜ ๊ฒƒ์ด๋ผ๊ณ  ์†Œ์ œ๋ชฉ์„ ์ง€์—ˆ์ง€๋งŒ, ๋‘๋ฒˆ์„ธ๋ฒˆ๋„ค๋ฒˆ๋‹ค์„ฏ๋ฒˆ์ƒ๊ฐํ•˜์žใ…กใ…ก

REF

profile
๊ฑฐ๋ถ์ด

2๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2020๋…„ 6์›” 5์ผ

๋ฐ˜์„ฑํ•˜๊ณ  ๋Œ์•„๋ณด๋Š” ๋ชจ์Šต ์ข‹์•„์š”~ ์ด์ด

1๊ฐœ์˜ ๋‹ต๊ธ€