일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 가천대
- 그래프
- 소켓
- dfs
- 쉬운 문제
- 문자열
- type challenge
- 크롤링
- 프로그래머스 레벨 2
- Node.js
- 타입 챌린지
- Crawling
- ip
- javascript
- Algorithm
- 수학
- BFS
- TCP
- 알고리즘
- typescript
- HTTP
- 타입스크립트
- 레벨 1
- 프로그래머스
- HTTP 완벽 가이드
- dp
- Nestjs
- 백준
- socket
- 자바스크립트
- Today
- Total
kakasoo
NestJS에 SpreadSheet API 사용하기 본문
구글에는 googleapis 라는 라이브러리 (* 아래 링크) 도 있지만 사용하지 않는 것이 좋다.
이 라이브러리의 경우 구글에서 제공하는 모든 API가 다 들어 있기 때문에 어플리케이션에서 쓰기엔 버겁다.
용량 자체가 120MB 정도가 되는데 서버 성능이 부족하면, 예를 들어 EC2가 t3.micro, small 급이라면,
그런 경우에는 서버를 빌드할 때 JavaScript의 Heap memory가 부족하다는 오류를 내뱉으며 멈추게 된다.
그렇기 때문에 만약,
- 스프레드시트를 생성한다.
- 데이터를 넣는다.
- 그 시트를 구글 드라이브를 이용해 다른 사람에게 공유한다.
와 같이, 스프레드시트 이후에 연계될 다음 동작들이 있지 않다면 npm에서 적절한 라이브러리를 찾는 게 낫다.
여기서 말하는 적절한 라이브러리는, 필요한 기능만 가지고 있는 더 작은 크기의 라이브러리를 말한다.
npm i google-spreadsheet
npm i --save-dev @types/google-spreadsheet
내가 찾은 라이브러리는 google-spreadsheet 였고, type이 제공되기 때문에 nest에서 용이하다.
google-spreadsheet library
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { readFileSync } from 'fs';
import { join } from 'path';
import { GoogleSpreadsheet, GoogleSpreadsheetRow } from 'google-spreadsheet';
@Injectable()
export class SpreadSheetService {
private readonly CREDENTIAL_PATH = join(__dirname, 'spread-sheet.json');
private readonly SCOPES = ['<https://www.googleapis.com/auth/spreadsheets>'];
constructor() {}
async loadGoogleSpreadSheet(sheetId: string) {
try {
const content = readFileSync(this.CREDENTIAL_PATH, { encoding: 'utf8' });
const credentials = JSON.parse(content);
const doc = new GoogleSpreadsheet(sheetId);
await doc.useServiceAccountAuth({
client_email: credentials.client_email,
private_key: credentials.private_key,
});
await doc.loadInfo();
return doc;
} catch (err) {
console.log(err.message);
return false;
}
}
async addRowsToSheet(row: Record<string, string="">, sheetName: string) {
const sheetId = '1htYnqW1jabJP6azHgRrFyuiE2MleLKx18DPTlyeI3kM';
const isLoadedDoc = await this.lightLoadGoogleSpreadSheet(sheetId);
if (isLoadedDoc) {
await isLoadedDoc.sheetsByTitle[sheetName].addRow(row);
}
}
}
</string,>
서비스는 이런 식으로 작성하면 된다.
서비스에 주어진 것은 구글 클라우드에 접근할 수 있도록 하는 API 인증 키로,
클라이언트의 이메일과 private key 를 가지고 있다.
순수하게 구글 라이브러리만 사용한다면 인증과, 인증이 없을 시의 로그인까지 구현해야 한다.
여기서 spread-sheet.json의 형식은 아래와 같다.
google API Key
{
"type": "service_account",
"project_id": "project_id",
"private_key_id": "private_key_id",
"private_key": "",
"client_email": "my.iam.gserviceaccount.com",
"client_id": "",
"auth_uri": "",
"token_uri": "",
"auth_provider_x509_cert_url": "",
"client_x509_cert_url": ""
}
키는 이런 형태다.
일부러 모든 값을 지웠는데, 이중에서 spread sheet API는 client_email, private_key만을 사용한다.
private_key는 우리가 알다시피 복호화를 위한 키로, pem 파일과 같이 암호화된 line들로 구성되어 있다.
중요한 것은, 이 키가 가리키는 계정이 해당 시트를 적절한 권한으로 공유받은 상태여야 한다는 것이다.
상식적으로 남의 시트를 API를 통해 제어할 수는 없으니깐.
loadGoogleSpreadSheet method
async lightLoadGoogleSpreadSheet(sheetId: string) {
try {
const content = readFileSync(this.CREDENTIAL_PATH, { encoding: 'utf8' });
const credentials = JSON.parse(content);
const doc = new GoogleSpreadsheet(sheetId);
await doc.useServiceAccountAuth({
client_email: credentials.client_email,
private_key: credentials.private_key,
});
await doc.loadInfo();
return doc;
} catch (err) {
console.log(err.message);
return false;
}
}
읽은 document를 반환하는 API를 만들었다.
addRow
async addRowToSheet(row: Record<string, string>, sheetName: string) {
const sheetId = '1htYnqW1jabJP6azHgRrFyuiE2MleLKx18DPTlyeI3kM';
const isLoadedDoc = await this.lightLoadGoogleSpreadSheet(sheetId);
if (isLoadedDoc) {
await isLoadedDoc.sheetsByTitle[sheetName].addRow(row);
}
}
sheetId는 google spreadsheet 페이지에 들어가면 바로 확인할 수 있다.
[<https://docs.google.com/spreadsheets/d/sheetId/edit#gid=0>](<https://docs.google.com/spreadsheets/d/sheetId/edit#gid=0>) 라는 URL 중간에서 확인 가능하다.
그 sheetId를 통해서 sheet들을 불러오면, 좌측 하단에 각 시트 별로 이름이 있다.
그 시트의 이름 (sheetName) 을 통해 원하는 시트 페이지만을 꺼내고, 이후 제어하는 게 가능하다.
왜 사용하는가?
데이터베이스에서 수집할 데이터와 구글 애널리틱스에서 수집할 데이터의 형태는 분명히 나뉜다.
그리고 이 둘 만으로도 충분하지만, 사용자에게 직접적으로 데이터를 요구할 경우에는 스프레드시트가 유용하다.
스프레드시트는 설문조사 형태로 된 데이터를 받아서 유저의 응답을 기록하기에 유리하고,
또 데이터베이스와 달리 모든 직군이 열람하기 편리한 형태다.
또 다른 직군이 업무에 활용하는 플랫폼들이 대개 스프레드시트를 통해 데이터를 받을 수 있는 경우가 많다.
예컨대 마케팅 쪽에서 활용하는 파이프드라이브가 그렇다.
개발자보다는 개발자가 아닌 사람들을 위해 작성하는 경우가 많으며, 그들이 인사이트를 얻게 도움을 준다.
'프로그래밍 > NestJS' 카테고리의 다른 글
Strategy, AuthGuard에서 에러 커스텀하기 (2) | 2023.01.29 |
---|---|
NestJS 모듈 배포를 위한 코드 작성 (0) | 2023.01.11 |
class-validator로 특정 날짜 검증하기 (0) | 2023.01.01 |
TypeORM에서 오늘 날짜의 데이터만 뽑기 (0) | 2022.12.25 |
Response DTO를 이용한 응답 직렬화 (Serialization) (0) | 2022.11.27 |