본문 바로가기
Programming/Javascript

Netlify Serverless function 작성

by Wilkyway 2021. 6. 17.
반응형

보안을 위해 API Key가 노출되지 않도록 API 요청 부분을 서버리스 함수로 작성하도록 하겠습니다.

추가로 API Key는 환경변수로 등록하여 Github 등으로 올릴 때 노출되는 것을 막기위해 추가적으로 보안설정을 하겠습니다.

 

1.netlify-cli 설치

npm i -D netlify-cli

2.netlify.toml

# Netlify Dev
# https://cli.netlify.com/netlify-dev/#netlifytoml-dev-block

# 제품 모드
[build]
  command = "npm run build"
  functions = "functions" # Netlify 서버리스 함수가 작성된 디렉토리를 지정합니다.
  publish = "build" # 프로젝트 빌드 결과의 디렉토리를 지정합니다.

# 개발 모드
[dev]
  framework = "#custom" # 감지할 프로젝트 유형을 지정합니다. 앱 서버 및 `targetPort` 옵션을 실행하는 명령 옵션은 `#custom`입니다.
  command = "npm run dev" # 연결할 프로젝트의 개발 서버를 실행하는 명령(스크립트)을 지정합니다.
  targetPort = 8080 # 연결할 프로젝트 개발 서버의 포트를 지정합니다.
  port = 8888 # 출력할 Netlify 서버의 포트를 지정합니다.
  publish = "public" # 프로젝트의 정적 콘텐츠 디렉토리를 지정합니다.
  jwtRolePath = "app_metadata.authorization.roles" # JWT 기반 리디렉션에 대한 역할 값을 찾아야하는 객체 경로를 지정합니다.
  autoLaunch = true # Netlify 서버가 준비되면 자동으로 브라우저를 오픈할 것인지 지정합니다.


3. package.json

 "scripts": {
    "dev": "snowpack dev",
    "dev:netlify": "netlify dev",
    "build": "snowpack build"
  },

4. /functions/movie.js

Netlify에서 작동할 서버리스 함수입니다. Netlify에서는 /functions/movie.js에 함수를 작성하게 되면, 'http://localhost:8079/.netlify/functions/movie' 와 같이 요청할 수 있습니다. node.js 환경에서 작동하므로 require로 모듈을 가져와야합니다.

const axios = require('axios')
const { OMDB_API_KEY } = process.env

exports.handler = async function(event, context) {
  const params = JSON.parse(event.body)
  const { title, type, year, page, id } = params
  //const OMDB_API_KEY='abd6b67a'

  const url = id 
    ? `https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&i=${id}&plot=full` 
    : `https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${title}&type=${type}&y=${year}&page=${page}`

  try{
    const res = await axios.get(url)
    console.log(res.data)
    if (res.data.Error) { //OMDB의 특수한 경우(정상반환되었으나 내용에 에러가 포함됨) 처리
      //reject(res.data.Error)
      return {
        statusCode: 400,
        body: res.data.Error
      }
    }
    //resolve(res)
    return {
      statusCode: 200,
      body: JSON.stringify(res.data)
    }
  } catch(error) {
    console.log(error.response.status)
    //reject(error.message)
    return {
      statusCode: error.response.status,
      body: error.message
    }
  }
}

 

5. 테스트용 app.svelte 소스

<script>
  import { fade } from 'svelte/transition'
  import Router,{ location } from 'svelte-spa-router'  
  import routes from '~/routes/index.js'
  import Header from '~/components/Header.svelte'  
  import Footer from '~/components/Footer.svelte'
  
  import axios from 'axios'

  async function test() {
    const res = await axios.get('/.netlify/functions/test')
    console.log(res)
  }
  test()
</script>

<Header />
{#key $location}
  <div in:fade>
    <Router 
      routes={routes} 
      restoreScrollState={true}/>
  </div>
{/key}
<Footer />

6. Netlify 환경변수에  OMDB_API_KEY 설정

경로: Netlify -> Site settings -> Build & deploy -> Environment -> Environment variables -> Edit Variables

 

7. 로컬서버에서도 테스트 가능하도록 환경변수 설정( .env 파일 생성)

OMDB_API_KEY=7035c60c

(주의) .gitignore에 추가하여 깃헙에 업로드되지 않도록 한다.

 

8. 추후 유지보수를 위한 설정 변경

1) package.json 시작 스크립트 변경

"scripts": {
    "dev:snowpack": "snowpack dev",
    "dev": "netlify dev",
    "build": "snowpack build"
  },

2) netlify.toml파일 변경

command를 바꿔주고, 시작 포트를 8079로 변경한다.

# 개발 모드
[dev]
  framework = "#custom" # 감지할 프로젝트 유형을 지정합니다. 앱 서버 및 `targetPort` 옵션을 실행하는 명령 옵션은 `#custom`입니다.
  command = "npm run dev:snowpack" # 연결할 프로젝트의 개발 서버를 실행하는 명령(스크립트)을 지정합니다.
  targetPort = 8079 # 연결할 프로젝트 개발 서버의 포트를 지정합니다.
  port = 8080 # 출력할 Netlify 서버의 포트를 지정합니다.
  publish = "public" # 프로젝트의 정적 콘텐츠 디렉토리를 지정합니다.
  jwtRolePath = "app_metadata.authorization.roles" # JWT 기반 리디렉션에 대한 역할 값을 찾아야하는 객체 경로를 지정합니다.
  autoLaunch = true # Netlify 서버가 준비되면 자동으로 브라우저를 오픈할 것인지 지정합니다.

3) snowpack.config.js 파일의 시작 포트 변경

module.exports = {
  mount: {
    public: '/',
    src: '/_dist_'
  },
  plugins: [
    '@snowpack/plugin-svelte',
    ['@snowpack/plugin-babel', {
      transformOptions: babelOptions()
    }],
    '@snowpack/plugin-dotenv',
    '@snowpack/plugin-optimize'
  ],
  alias: {
    '~': './src'
  },
  devOptions: {
    port: 8079
  }
}
반응형

댓글