포켓몬 API 만들어서 배포하기
Table of contents
이 페이지에서 안내하는 작업의 내용은 코파일럿 플러그인과 연동하는 목업 API를 만드는 과정입니다. 이미 사용하려고 하는 API 를 따로 가지고 있다면, 이 과정을 생략하여도 무방합니다만 공부하는 차원에서는 원하는 데이터를 제공하는 API 부터 그걸 활용하는 플러그인까지 모두 만들어 보는 것이 도움이 될 것입니다.
꼭 그래야만 하는 것은 아니지만, 여기에서는 애저 펑션(Azure Function)을 이용하겠습니다. 애저 펑션을 이용하여 빠르고 쉽게 내가 원하는 데이터를 검색할 수 있는 목업 API를 만들 수 있습니다.
이 작업에서 만드는 목업 API는 인증 없는 anonymous API 입니다. 테스트를 위한 용도이기 때문입니다. 향후 프로덕션 환경에서 API를 개발하고 활용하실 때에는 인증체계까지 고려된 API를 설계하고 구현하시기 바랍니다.
1. VS Code에 Azure Function Extension 설치
VS Code 에서 애저 펑션 익스텐션을 이용하면 쉽고 간단하게 API를 개발하고 배포할 수 있습니다. 먼저 익스텐션을 설치해야 합니다. 왼쪽 메뉴에서 Extensions 아이콘을 클릭하여 Azure Function을 검색하여 익스텐션을 설치해 주십시오.
2. Azure Function 프로젝트 만들기
이제 익스텐션이 제공하는 프로젝트 템플릿으로 API 프로젝트를 만들어 보겠습니다.
2-1. 템플릿으로 프로젝트 생성
애저 펑션 익스텐션이 설치되면 VS Code의 왼쪽 메뉴에 A 아이콘이 나타납니다. 이 아이콘을 클릭하여 애저 펑션 익스텐션 화면으로 이동합니다. 익스텐션 패널의 아래쪽에 있는 Create Function Project 를 클릭합니다.
프로젝트를 어디에 만들 것인지 물어보는 창이 뜹니다. 원하는 폴더를 찾아 이동하여 프로젝트 용 폴더까지 만들어 줍니다.
만들어진 폴더 안으로 이동하여 Select 버튼을 클릭합니다.
어떤 언어로 개발할 것인지 물어봅니다. 각자 자신있는 개발언어로 선택해도 됩니다만, 여기에서는 JavaScript를 선택하여 진행하겠습니다. 향후에 다른 API를 만들 때 익숙하고 자신있는 개발언어를 선택하여 활용해 보시는 것을 추천합니다.
Model V4 를 선택합니다.
HTTP trigger 를 선택합니다.
httpTrigger 의 이름을 정해주어야 합니다. 저는 getPokeData 라고 이름 지었습니다. 적절한 이름으로 지어서 입력해 주십시오. 이 정보가 향후 API를 호출하는 URL에 사용됩니다.
Open in current window 를 선택합니다.
VS Code 가 새로운 API 프로젝트를 만들고 새 창으로 띄웁니다.
2-2. F5를 눌러 디버깅 모드로 실행해보기
방금 만든 API가 잘 구동되는지 로컬환경에서 먼저 테스트 해보겠습니다.
프로젝트가 뜬 VS Code 에서 F5 키를 눌러 로컬 디버깅을 시작해 보겠습니다. 만약 최초 실행이라면 애저 펑션 코어 툴을 설치해야 한다는 메세지 확인 창이 뜹니다. Install 버튼을 클릭하여 설치를 진행합니다.
VS Code 에서 애저 펑션 코어 툴 이 설치됩니다.
설치가 완료된 후 다시 F5를 누릅니다. 이번에는 스토리지 어카운트 관련 메세지 창이 뜹니다. Use Local Emulator 버튼을 클릭합니다. (이 메세지 창은 나중에 디버깅을 시작할 때 계속 보여질 수 있습니다.)
연속해서 뜨는 메세지 창에서 Debug anyway 버튼을 클릭합니다.
디버깅을 위해 프로젝트가 빌드되고 로컬환경에서 수행되기 시작합니다.
로컬환경에 따라 아래와 같이 네트워크 엑세스 허용 확인 창이 뜰 수 있습니다. 허용 을 클릭합니다.
디버깅 준비가 완료되면 VS Code의 터미널 인터페이스에서 테스트 할 수 있는 URL을 확인할 수 있습니다. http://localhost:7071/api/만든트리거이름 의 형식으로 만들어 집니다.
해당 주소를 브라우저로 접속해 보면 Hello, world! 가 나옵니다. API 프로젝트가 잘 만들어 졌네요.
디버깅을 종료하려면 Shift 키와 F5 키를 동시에 누르거나, 디버깅 도구에서 Disconnect 버튼을 클릭합니다.
3. 코드를 수정하여 포켓몬 API 만들기
3-1. 데이터 JSON 준비하기
PokemonGO-Pokedex-Korean
이 프로젝트에서 사용하는 포켓몬 데이터는 아래 프로젝트의 결과물을 사용합니다. https://github.com/intelcoder/PokemonGO-Pokedex-Korean
이 주소(https://lanslote.github.io/copilot/plugin-ME-HOL/assets/30/pokedex-korean.json)에서 pokedex-korean.json 파일을 다운로드 받아 프로젝트의 functions 폴더에 추가해 줍니다.
3-2. getPokeData.js 코드 변경
이제 functions 폴더 아래에 있는 getPokeData.js 를 열어 그 안의 코드를 변경해 보겠습니다.
코드에서 아래의 내용을 찾습니다.
1
2
3
const name = request.query.get('name') || await request.text() || 'world';
return { body: 'Hello, ${name}!' };
아래의 코드로 바꿉니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
const param_num = request.query.get("num");
const param_name = request.query.get("name");
const param_type = request.query.get("type");
const pokemondata = require("./pokedex-korean.json");
let mypokemon = pokemondata;
if (!(param_num) && !(param_name) && !(param_type)) {
return { body: `{ "pokemons" : []}` };
}
else {
if (param_name != "all"){
if (param_num) {
mypokemon = mypokemon.filter((item) => {
return (
item.num.toLocaleLowerCase() == param_num.toLocaleLowerCase()
);
});
}
if (param_name) {
mypokemon = mypokemon.filter((item) => {
return (
item.name.toLocaleLowerCase().includes(param_name.toLocaleLowerCase())
);
});
}
if (param_type) {
mypokemon = mypokemon.filter((item) => {
return (
item.type.toLocaleLowerCase().includes(param_type.toLocaleLowerCase())
);
});
}
}
return { body: `{ "pokemons" : ${JSON.stringify(mypokemon)} }` };
}
코드가 변경된 화면입니다.
getPokeData.js 의 전체 코드는 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const { app } = require('@azure/functions');
app.http('getPokeData', {
methods: ['GET', 'POST'],
authLevel: 'anonymous',
handler: async (request, context) => {
context.log(`Http function processed request for url "${request.url}"`);
//const name = request.query.get('name') || await request.text() || 'world';
const param_num = request.query.get("num");
const param_name = request.query.get("name");
const param_type = request.query.get("type");
const pokemondata = require("./pokedex-korean.json");
let mypokemon = pokemondata;
if (!(param_num) && !(param_name) && !(param_type)) {
return { body: `{ "pokemons" : []}` };
}
else {
if (param_name != "all"){
if (param_num) {
mypokemon = mypokemon.filter((item) => {
return (
item.num.toLocaleLowerCase() == param_num.toLocaleLowerCase()
);
});
}
if (param_name) {
mypokemon = mypokemon.filter((item) => {
return (
item.name.toLocaleLowerCase().includes(param_name.toLocaleLowerCase())
);
});
}
if (param_type) {
mypokemon = mypokemon.filter((item) => {
return (
item.type.toLocaleLowerCase().includes(param_type.toLocaleLowerCase())
);
});
}
}
return { body: `{ "pokemons" : ${JSON.stringify(mypokemon)} }` };
}
}
});
3-3. F5를 눌러 디버깅 모드로 실행해보기
코드 변경이 마무리되었으면, 로컬 디버깅 모드로 실행해서 테스트해봐야 합니다.
프로젝트에서 F5 키를 눌러 디버깅을 시작합니다. 애저 스토리지 관련 경고창이 뜰 수 있습니다. Debug anyway를 클릭하여 계속 진행하도록 합니다.
디버그 준비가 완료되면 터미널 창에 테스트 할 수 있는 주소를 확인할 수 있습니다.
getPokeData API의 파라미터
API는 두 가지의 파라미터에 대응할 수 있도록 코드가 작성되어 있습니다.
- name :: 이름으로 포켓몬을 검색 (포함된 문자로 검색)
- type :: 타입으로 포켓몬을 검색 (호함된 문자로 검색) 두가지의 파라미터를 모두 사용해도 동작하도록 작성되어 있습니다.
name 파라미터를 이용해서 이름으로 포켓몬을 검색
type 파라미터를 이용해서 타입으로 포켓몬을 검색
name 파라미터에 all 을 주면 모든 데이터를 반환합니다.
4. Azure 클라우드에 Azure Function 배포하기
로컬 환경에서 API 동작을 검증하였으니, 이제 애저 클라우드에 배포할 차례입니다. 이렇게 한번 배포해 놓으면 계속 테스트에 활용가능합니다.
4-1. Azure 클라우드에 로그인하기
애저 펑션을 클라우드에 배포하기 위해서는 구독을 사용할 수 있는 계정이 필요합니다. 다음과 같이 배포에 사용할 애저 계정을 툴에 입력해 놓아야 합니다.
VS Code의 왼쪽 메뉴에서 A 아이콘을 클릭해 애저 펑션 익스텐션을 엽니다. 패널의 상단에 있는 Resources 섹션에서 Sign in to Azure을 찾아 클릭합니다.
확인창에서 Allow 버튼을 클릭합니다.
애저 구독에 권한이 있는 계정으로 로그인합니다.
패스워드도 입력합니다.
사인인이 끝나면 이 창은 닫아도 됩니다.
4-2. Azure 구독 선택하기
로그인 후 계정과 연결된 구독중 배포에 사용할 구독을 선택해야 할 수도 있습니다. 이 핸즈온 랩에서는 M365의 계정을 다른 애저 테넌트의 게스트로 초대하여 권한을 부여하는 방식으로 구성하였기 때문에 Azure와 M365를 단일 테넌트로 사용하는 환경에서는 필요 없을 수도 있습니다.
Resources 섹션에서 Sign in to Directory 를 찾아 클릭합니다.
현재 사인인한 계정과 연결된 디렉토리의 목록이 펼쳐집니다. 애저 구독이 있는 테넌트를 찾아 클릭합니다.
확인창에서 Allow 버튼을 클릭합니다.
애저 구독에 권한이 있는 계정으로 로그인합니다.
등록이 완결되면 해당 구독의 이름이 표시되고, 그 하위에 구성가능한 서비스의 목록이 보여집니다.
4-3. 로컬 프로젝트를 클라우드에 배포하기
애저 구독관련 설정이 완료되었으니 이제 로컬 프로젝트를 글라우드에 배포할 수 있습니다.
패널 하위의 WorkSpace 에 있는 Local Project 를 마우스 오른쪽 클릭하여 Deploy to Azure를 클릭합니다.
최초 배포이므로 새로 펑션앱을 만들어야 합니다. Create new function app을 선택합니다.
펑션앱의 이름을 지어줘야 합니다. 이 이름은 전체 애저 글로벌 환경에서 유일한 이름이어야 합니다. 중복되지 않을만한 이름으로 지어서 입력해 주세요.
Node.js 18 LTS 를 선택합니다.
Korea Central 지역을 선택합니다.
간혹 실패할 수도 있는데, 다시 실행해보십시오.
작업이 완료되면 Output 창을 엽니다.
아웃풋 창에서 클라우드에 배표된 API의 URL을 확인할 수 있습니다.
4-4. 배포된 API 테스트
클라우드에 배포된 API 를 브라우저로 접속하여 name 과 type 파라미터를 사용해 테스트 해봐야 합니다.
4-5. 클라우드 API 주소 확보
포켓몬 데이터를 검색할 수 있는 API를 만들었습니다. 이 API를 이용한 플러그인을 만들기 위해 아래와 같은 포맷의 API URL을 확보하여 따로 저장해 두십시오.
https://클라우드프로젝트명.azurewebsites.net/api/getpokedata?name=all https://클라우드프로젝트명.azurewebsites.net/api/getpokedata?name=단데기 https://클라우드프로젝트명.azurewebsites.net/api/getpokedata?type=벌레
Azure Functions 사용량 과금제는 초당 리소스 사용량과 실행 횟수에 따라 비용이 청구됩니다. 사용량 플랜 가격에는 종량제 가격 체제로 구독 내의 모든 함수 앱에 대해 구독별로 매월 1백만 건의 요청 및 매월 400,000GB의 리소스 사용이 무료로 부여됩니다. Azure Functions 프리미엄 플랜은 향상된 성능을 제공하고 프리미엄 Functions에서 사용하는 vCPU-s 및 GB-s 수를 기준으로 초 단위로 요금이 청구됩니다. 또한 고객은 사용 중인 App Service 계획에서 App Service 계획의 정가로 Functions를 실행할 수 있습니다.
https://azure.microsoft.com/ko-kr/pricing/details/functions/