Nodejs, Expressjs, Google Sheet를 사용하여 API - 시리즈 1 구축 방법

전자 표에 많은 작업을 했습니다. 이 데이터를 관계 데이터베이스나 NoSql 데이터베이스로 이동하지 않고 Nodejs 응용 프로그램에 통합하는 방법을 알고 싶으십니까?
이것은 가능한 것입니다. 당신은 본문에서 그것을 어떻게 완성하는지 배울 것입니다.
Google Sheet는 여전히 현재 소기업의 중요한 도구입니다.나는 몇몇 초창기 회사들이 구글 폼에서 시작된 것을 알고 있다. 그들이 확장이 필요하다는 것을 발견하고 나서야 응용 프로그램을 만들고 진정한 데이터베이스로 옮길 수 있다.
Google Sheet가 아닌 실제 백엔드 데이터베이스를 사용해야 하는 이유는 많지만 예기치 않은 데이터 삭제나 워크시트, 기록에 정적 식별자가 부족한 이유 등이 있다.
그러나 본고는sheet가 실제 백엔드 데이터베이스에 대한 장점을 논의하고자 하는 것이 아니다. 반대로, 일부 항목은sheet에서 데이터를 읽고 응용 프로그램/데이터베이스에 동기화하거나 관리하기 위해sheet에 쓰도록 요구한다.
대부분의 작은 프로젝트는 일반적인 데이터베이스가 필요하지 않을 수도 있고 Google Sheet를 사용하여 관리할 수 있습니다.
이 문서에서는 Nodejs를 사용하여 Google Sheet를 읽는 과정을 안내합니다.

선결 조건


이 강좌에서는 Google Sheet를 읽고 쓰는 rest API를 만듭니다.
이 강좌를 시작하기 전에 다음이 필요합니다.

  • Nodejs 및 설치된 NPM
  • 웹 브라우저
  • 인증된 구글 계정 사용
  • 시작합시다...

    Google Sheet API 활성화


    Google sheet API는 Google의 API로 개발자가 응용 프로그램에서 Google sheet를 프로그래밍, 쓰기, 포맷할 수 있도록 합니다.
    1단계).다운로드 credentials.jsonthis link를 따르고 Google Sheets API 사용 단추를 눌러 파일 다운로드credentials.json
    다음과 같이 항목 이름을 입력해야 합니다.

    통합할 응용 프로그램 유형으로 웹 서버 ****를 선택한 다음 *API 콘솔 *를 클릭하여 URI 재지정 구성

    콘솔에서 자격 증명 선택 및 편집OAuth client
    URI로 다시 지정하고 저장할 수 있는 권한을 부여합니다.(이 URI는 구글 인증 후 리디렉션된 곳입니다. 이것은 절대적인 경로일 것입니다.)

    마지막으로 자격 증명 다운로드

    참고: 이 강좌는 다운로드한 자격 증명의 이름을 * 자격 증명으로 가정합니다.json*, 파일을 사용하고 싶은 이름으로 바꿀 수 있으며, credentials.json 파일을 본문에서 사용할 파일 이름으로 바꿀 수 있습니다.
    2단계).설치에 필요한 NodeJS 패키지
    npm install googleapis@39 express http --save
    npm install nodemon --save-dev
    

    API 만들기


    폴더 구조


    우리의 폴더 구조는 다음과 같다
    server.js 파일에 서버 시작 및 실행 코드 포함
    서버에 다음 코드를 추가합니다.js 파일.
        const PORT = process.env.PORT || 3000;
        const http = require('http');
        const app = require('./routes/app')
        const server = http.createServer(app);
        server.listen(PORT)
    
    routes 폴더에서 프로그램을 만듭니다.js 및 다음 코드 추가
        const express = require('express');
        const indexRoute = require('../routes/index')
        const app = express();
        app.use((req, res, next) => {
          res.setHeader('Access-Control-Allow-Origin', '*');
          res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content, Accept, Content-Type, Authorization');
          res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
          next();
        });
        app.use('/', indexRoute);
        module.exports = app;
    
    터미널에 nodemon 를 입력하여 서버를 시작합니다. 이것은 입력 node server.js 과 같습니다.다른 점은 node server.js 을 사용하면 코드를 변경할 때마다 서버를 멈추고 다시 시작해야 한다는 것입니다.그러나 Nodemon을 사용하면 디렉터리의 파일이 변경되면 자동으로 프로그램을 다시 시작합니다.Nodemon은 서버를 시작하는 것을 알고 있습니다.내 가방에 지정되어 있기 때문이다.json 파일"main": "server.js".서버가 http://localhost:3000 에서 실행되어야 합니다.
    * 자격 증명을 복사합니다.json*구글 폴더에 들어갑니다.
    다음은 클래스 모듈을 만드는 코드입니다. 저희 프로그램에서sheetapi를 사용하도록 검증하고 권한을 부여하는 데 사용됩니다.
        const fs = require('fs')
        const readline = require('readline')
        const {google} = require('googleapis')
        // If modifying these scopes, delete token.json.
        // SCOPE gives additional rules to the sheet, you can restrict rule to readonly or give full access
        const SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
        // The file token.json stores the user's access and refresh tokens, and is
        // created automatically when the authorization flow completes for the first
        // time.
        // The path were your token.json file is saved, depends totally on you.
        const TOKEN_PATH = './google/token.json'
        class Authentication {
          authenticated(){
            return new Promise((success, failed) => {
              // Load client secrets from a local file.
                let credentials = this.getClientSecret()
                let authorized = this.authorize(credentials)
                authorized.then(success, failed)
              })
    
          }
          getClientSecret(){
            return require('./credentials.json')
          }
    
          /**
           * Create an OAuth2 client with the given credentials, and then execute the
           * given callback function.
           * @param {Object} credentials The authorization client credentials.
           * @param {function} callback The callback to call with the authorized client.
           */
          authorize(credentials) {
            const {client_secret, client_id, redirect_uris} = credentials.web
            const oAuth2Client = new google.auth.OAuth2(
                client_id, client_secret, redirect_uris[0])
    
                return new Promise((success, failed) => {
                  // Check if we have previously stored a token.
                  fs.readFile(TOKEN_PATH, (err, token) => {
                    if (err) {
                      this.getNewToken(oAuth2Client)
                      .then((oAuth2ClientNew) => {
                        success(oAuth2ClientNew)
                      }, (err) => {
                        failed(err)
                      })
                    } else {
                      oAuth2Client.setCredentials(JSON.parse(token))
                      success(oAuth2Client)
                    }    
                  })
                })
            }
    
          /**
           * Get and store new token after prompting for user authorization, and then
           * execute the given callback with the authorized OAuth2 client.
           * @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
           * @param {getEventsCallback} callback The callback for the authorized client.
           */
          getNewToken(oAuth2Client, callback) {
            return new Promise((success, failed) => {
              const authUrl = oAuth2Client.generateAuthUrl({
                access_type: 'offline',
                scope: SCOPES,
              })
              console.log('Authorize this app by visiting this url:', authUrl)
              const rl = readline.createInterface({
                input: process.stdin,
                output: process.stdout,
              })
              rl.question('Enter the code from that page here: ', (code) => {
                rl.close()
                oAuth2Client.getToken(code, (err, token) => {
                  if (err) {
                    failed('Error while trying to retrieve access token', err)
                  } 
                  oAuth2Client.setCredentials(token)
                  // Save the token for later program executions
                  fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
                    if (err) return console.error(err)
                    console.log('Token stored to', TOKEN_PATH)
                  })
                  success(oAuth2Client)
                })
              })
            })
          }
        }
    
        module.exports = new Authentication
    
    색인을 만듭니다.js 파일 내의 구글 폴더를 붙여넣고 위의 코드를 붙여넣습니다.

    우리의 노선을 창설하다


    루트 폴더에 index.js 파일을 만들고 다음 코드를 추가합니다.이것은 이 프로그램의 모든 경로를 포함해야 합니다.
        const express = require('express')
        const router = express.Router()
        const { retrieveUsers } = require('../controllers/retrieveFromSheet')
        const { saveUsers } = require('../controllers/saveToSheet')
    
        router.get('/v1/users', retrieveUsers)
        router.post('/v1/update/users', saveUsers)
    
        module.exports = router
    

    우리 컨트롤러 만들기


    컨트롤러 폴더에서 *retrieveFromSheet를 만듭니다.js* 및 saveToSheet.회사 명

    애플리케이션 확인


    응용 프로그램이 Sheet에 액세스하여 다운로드하도록 하겠습니다token.json.
    이 코드를 retrieveFromSheet.js에 추가
        const authentication = require('../google/index')
        const { google } = require('googleapis')
    
        exports.retrieveUsers = (req, res) => {
        authentication.authenticated()
          .then((auth) => {
            res.status(200)
            .json('Working')
          })
          .catch(err => {
            res.status(401)
            .json(`you know wetin happen, ${err}`)
          })
        }
    
    브라우저에서 *localhost:3000/v1/users*를 열고 터미널로 돌아가기

    터미널에서 URL을 엽니다.이 링크를 자세히 보면 구글 개발자 컨트롤러에 설정된 redirect_uri 을 추가한 것을 발견할 수 있다.
    응용 프로그램에 필요한 모든 액세스 권한을 제공하고 계속하면 redirect_uri 로 방향을 바꾸고 경로에 코드를 추가합니다.

    코드를 복사해서 터미널에 붙여넣고 enter 키를 누르십시오.구글 폴더를 열면 * 영패를 볼 수 있습니다.json, 네비게이션 회*http://localhost:3000/v1/users** 모든 것이 순조롭다면 보아야 한다

    작업표에서 데이터를 검색하기 위해 함수를 추가합시다
        const getFromSheet =  (auth) => {
          return new Promise((success, failed) => {
            const sheets = google.sheets({version: 'v4', auth})
            sheets.spreadsheets.values.get({
              spreadsheetId: '1_c4TS8WO0VqX336OauvYaVlxRzuEkaZ50hJf6yQxZok',
              range: 'approved!A:D',
            }, (err, res) => {
              if (err){
                return failed(err) 
              }
              const rows = res.data.values
              success(rows)
            })
          })
        }
    
    retrieveUsers에서 호출getFromSheet
        getFromSheet(auth).then((response) => {
          res.status(200).
          json(response)
        })
        .catch(err => {
          console.log(`i no gree fetch data from sheet, ${err}`)
        })
    
    res 표에서 데이터를 되돌려줍니다. 상태 코드, 헤더, url, 방법 유형 등을 포함하지만 우리의 관심은 res.data.values 입니다.
    *localhost:3000/v1/users*를 새로 고칩니다. 저희가 검색한 사용자는 하나의 그룹이어야 합니다.

    이제 검색한 사용자를 포맷해서 더 예뻐 보이게 합시다.
    * 워크시트에서 읽어들입니다.js*이랬을 거예요.
        const authentication = require('../google/index')
        const { google } = require('googleapis')
        const getFromSheet =  (auth) => {
          return new Promise((success, failed) => {
            const sheets = google.sheets({version: 'v4', auth})
            sheets.spreadsheets.values.get({
              spreadsheetId: '1_c4TS8WO0VqX336OauvYaVlxRzuEkaZ50hJf6yQxZok',
              range: 'approved!A:D',
            }, (err, res) => {
              if (err){
                return failed(err) 
              }
              const rows = res.data.values
    
              // format retrieved data
              if (rows.length) {
                  var rowHead = rows.shift()
                  const formatedUsers = rows.map((row) => {
                      return rowHead.reduce( (obj, key, i) => {
                        obj[key] = row[i]
                        return obj
                      }, {})
                  })
                  success(formatedUsers)   
              } else {
                failed('No data found.')
              }
            })
          })
        }
        exports.retrieveUsers = (req, res) => {
          authentication.authenticated()
          .then((auth) => {
            getFromSheet(auth).then((response) => {
              res.status(200)
              .json({
                message: response
              })
            })
            .catch(err => {
              res.status(404)
              .json({
                error: `i no gree fetch data from sheet, ${err}`
              })
            })
          })
          .catch(err => {
            res.status(401)
            .json({
              error: `you know wetin happen, ${err}`
            })
          })
        }
    
    사용자는 이렇게 해야 한다

    더 잘 이해하기 위해서 우리는 처음부터 코드 라이브러리를 다시 한 번 시도합시다.
        sheets.spreadsheets.values.get({
              spreadsheetId: '1_c4TS8WO0VqX336OauvYaVlxRzuEkaZ50hJf6yQxZok',
              range: 'approved!A:D',
            }
    

    범위


    범위는 워크시트의 단일 셀 또는 워크시트의 인접 셀 그룹일 수 있습니다.예를 들어 우리 위의 코드에서 우리는 하나의 범위를 지정했다. - 승인!A:D.*approved*는 다음 그림과 같이 시트 이름을 가리킵니다.
    전체 작업표를 작업장이라고 부른다

    !A:D는 A열에서 D열로 시작됨을 나타냅니다.
    !B2: D3는 B열 두 번째 줄부터 D열 세 번째 줄까지 표시됩니다.
    가치관get은 위의 예시와 같이 단일 범위에서 값을 검색하는 데 사용됩니다.
    가치관batchGet은 여러 범위에서 동시에 검색하는 데 사용됩니다.
    batchGet을 사용하려면 범위를 ranges: ['approved!B2:D3', 'approved!A1:C2'] 로 변경하십시오. 범위가 다른 그룹이 필요합니다.batchGet을 사용하여 res.data.valueRanges 에서 반환된 데이터를 제거합니다.
    스프레드시트 id: "1_c4TS8WO0VqX336OauvYaVlxRzuEkaZ50hJf6yQxZok", 스프레드시트 id는 워크북의 id를 가리킨다

    승낙


    약속은 비동기적인 조작의 완성(또는 실패)을 가리킨다.약속은 한 번만 성공하거나 실패할 수 있다.
    여기서 우리는 성공이나 실패의 대상으로 돌아가겠다고 약속한다
        const getFromSheet =  (auth) => {
          return new Promise((success, failed) => {
    

    결론


    우리가 방금 작업표에서 검색한 데이터는 응용 프로그램의 분석에 사용되고 심지어 진정한 백엔드 데이터베이스에 저장될 수 있다.다음 글에서 우리는 구글 폼에 어떻게 저장하고 더 많이 저장하는지 볼 것이다.
    따라와, 우리 연결하자.

    좋은 웹페이지 즐겨찾기