Youtube의 Data (실시간 인기 동영상) 를 마음껏 호출하고 쓰고 싶었으나, 할당량이 매우 적어 클라이언트마다 Data API 를 호출하면 순식간에 고갈될 것이 예상되었습니다.
그리하여 중간에 캐시 느낌으로 아래와 같이 구성하려고 합니다.
1.
Cloud Function 에서 5분 주기로 API 호출 및 저장
2.
Response 를 Firebase firestore 에 업데이트
3.
클라이언트에서는 firestore 에 있는 값을 이용
이런식으로 Third-party API 를 이용할 때 외부 장애에 대한 안정성을 다소? 높일 수 있고, API 횟수 제한을 회피 할 수 있는 장점이 있을 것 같습니다
시작
Cloude Function을 이용하기 전 firebase-tools 를 설치 후 프로젝트를 설정합니다
npm install -g firebase-tools // firebase-tools 설치
firebase login // Firebase 콘솔 기능을 사용할 수 있도록 로그인
firebase init functions // Cloud function 기능 활성화
Bash
복사
Conolse 에서 몇가지 질문들 던지지만, 전부 Default 로 설정을 해줍니다
이 과정들을 거치고 나면 아래의 디렉토리 구조가 생성됩니다
myproject
+- .firebaserc # 숨김 파일로 무시해주세요
|
|
+- firebase.json # 프로젝트 설정
|
+- functions/ # 실행되는 함수, 구현체들이 있는 디렉토리
|
+- .eslintrc.json # lint 룰. 옵셔널
|
+- package.json # npm package file
|
+- index.js # main source file for your Cloud Functions code
|
+- node_modules/ # directory where your dependencies (declared in
# package.json) are installed
출처) Firebase 공식 가이드 문서 (https://firebase.google.com/docs/functions/get-started?hl=ko)
Bash
복사
예제
처음은 역시 어려운 것이니 예제를 이용해 보도록 합니다.
functions/index.js 에 아래 예제를 복붙해봅니다.
예제에서 Key 는 수정해주세요. (유튜브 API Key 발급받기)
var request = require('request');
var api_url = 'https://content.googleapis.com/youtube/v3/search?order=rating®ionCode=kr&key={Youtube API Key}&maxResults=50';
request.get({
url: api_url,
headers: {
'Content-Type': 'application/json'
}
},
function (error, response, body) {
console.log(response.statusCode);
console.log(body);
});
JavaScript
복사
테스트
firebase emulators:start
Bash
복사
위 명령어를 이용하면 작성한 function 을 실행시킬 수 있다고 합니다.
실행해 보면
한번에 되는 것은 없지
Error: Cannot find module 'request'
다행히 익숙한 에러입니다. npm 모듈이 없을 때 발생하는 오류입니다.
npm install request
Bash
복사
request 모듈을 설치하고 에뮬레이터를 다시 실행합니다.
50개의 유튜브 영상 목록을 가져오는데 성공했습니다
Firestore 에 저장하기
위 과정에서 가져온 Youtube ID 들을 Firestore 에 저장합니다
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp()
const firestore = admin.firestore();
var request = require('request');
var api_url = 'https://content.googleapis.com/youtube/v3/search?order=rating®ionCode=kr&key={YOUTEBE_API_KEY}&maxResults=50';
function js_yyyy_mm_dd_hh_mm_ss () {
now = new Date();
year = "" + now.getFullYear();
month = "" + (now.getMonth() + 1); if (month.length == 1) { month = "0" + month; }
day = "" + now.getDate(); if (day.length == 1) { day = "0" + day; }
hour = "" + now.getHours(); if (hour.length == 1) { hour = "0" + hour; }
minute = "" + now.getMinutes(); if (minute.length == 1) { minute = "0" + minute; }
second = "" + now.getSeconds(); if (second.length == 1) { second = "0" + second; }
return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
}
request.get(api_url,
function (error, response, body) {
if (response.statusCode == 200) {
var res = JSON.parse(body);
var videoIDs = res["items"].map((v) => { return v.id }).map((v) => { return v.videoId }).join(',');
firestore.collection('content').doc("youtube").set(JSON.parse(JSON.stringify({"ids" : videoIDs, "latest_updated_at": js_yyyy_mm_dd_hh_mm_ss()})));
}
});
JavaScript
복사
결과는
10,000 units per day 뿌수기
Youtube API의 limit 은 10,000 per day
1분에 1번씩 호출하면 하루 24 * 60 = 1440 충분히 여유있습니다
"Blaze 요금제" 에서 사용할 수 있다고 합니다.
예제코드
exports.scheduledFunction = functions.pubsub.schedule('every 5 minutes').onRun((context) => {
console.log('This will be run every 5 minutes!');
return null;
});
JavaScript
복사
여기서 every 5 minute ⇒ every 1 minute 로 변경하고 closure? javascript 에서도 closure 라고 부르나..?
에 위에서 작성한 함수를 넣으면 될 듯 합니다.
종량제도 Blaze 로 바꾸고, firebase console 로 최신으로 업뎃 후 성공
결과
1분마다 업데이트 됨을 확인 할 수 있습니다