cloudflare workers + faunaDB 시작하기
🛩️

cloudflare workers + faunaDB 시작하기

생성일
Feb 4, 2022 12:04 PM
태그
cloudflare
fauna
위 링크의 가이드를 보고 따라해봤습니다.
 

Cloudflare 작업자와 Fauna를 사용하는 이유는?

faunaDB는 HTTP 기반의 연결 모델 덕분에 workers와 원활하게 통합될 수 있다. 두 서비스 모두 사용하는 애플리케이션은 서버리스 엔드 투 엔드로 실행할 수 있으며 인프라를 관리할 필요없이 무한히 확장할 수 있다.
일반적으로 서버는 단일 위치에서 로직과 데이터베이스 쿼리를 실행한다. Worker + Fauna를 사용하면 데이터와 코드가 여러 위치에서 실행되고 왕복 읽기 대기 시간을 크게 줄일 수 있다.
 

만들 것

간단한 제품 인벤토리를 관리하는 CRUD 기능이 있는 js REST API
{
	title: string,
	serialNumber: string,
	weightLabs: float,
	quantity: int
}
위 형식의 데이터가 포함된다.
Fauna의 컬렉션은 단순한 도큐먼트 버킷이다.
 

요구사항

  • Node
  • Cloudflare wrangler CLI
 

Fauna 설정

디비 생성

 
notion image
먼저 Fauna 대쉬보드에 접속하여 새 데이터베이스를 생성합니다.
 
 

컬렉션 생성

 
notion image
다음 인벤토리에 대한 문서를 저장할 프로덕트 컬렉션을 생성합니다.
CreateCollection({ name: "Products" })
위의 FQL 쿼리로 컬렉션을 생성했습니다. 옆의 Collections 탭에서 GUI 로 생성할 수도 있습니다.
 
CreateCollection({ name: "Products" })

{
  ref: Collection("Products"),
  ts: 1643977115450000,
  history_days: 30,
  name: "Products"
}

>> Time elapsed: 154ms
FQL 실행 후 위의 리턴값을 얻었는데요, 각각 데이터의 정보는 아래와 같습니다.
ref - 컬렉션 자체에 대한 참조
ts - 생성 타임스탬프
history-days - Fuana가 컬렉션 문서의 변경 사항을 유지하는 기간을 결정
name - 컬렉션 이름
 
 

서버 키 생성

notion image
대쉬보드의 좌측 보안탭에서 생성할 수 있습니다.
 

Worker 설정

설치

npm i @cloudflare/wrangler -g
wrangler login
wrangler 설치 후 cloudflare 계정 로그인을 합니다.
 

wrangler 설정

wrangler generate fauna-workers
위 명령어로 workers 프로젝트를 생성합니다.
 
wrangler.toml
name = "fauna-workers"
type = "javascript"

account_id = ""
workers_dev = true
route = ""
zone_id = ""
compatibility_date = "2022-02-04"
그후 toml 파일에 정보를 기입합니다.
 
wrangler publish
이상태에서 위 명령어를 실행하면 hello worker 페이지가 project-name.userId.workers.dev url에 배포됩니다. cloudflare 사이트의 worker 대쉬보드에도 설정한 프로젝트가 자동으로 생성됨을 볼 수 있습니다.
 

fauna 비밀키 등록

wrangler secret put FAUNA_SECRET
worker가 생성 및 배포되면 cloudflare의 인프라에 fauna 키를 안전하게 저장할 수 있습니다.
위 명령어를 실행한 후 이전에 얻은 fauna 서버 암호를 붙여 넣습니다.
wrangler.toml 에서 직접 환경 변수를 구성하는 것보다 더 안전한 방법인듯 하네요.
 
 

종속성 설치

yarn add faunadb
faunadb는 데이터베이스 드라이버이고, worktop은 worker를 더 편하게 사용할 수 있도록 하는 프레임워크입니다.
 
원글에서는 worktop 프레임워크를 사용하지만 아래 에러로 제외했습니다.
Error: The package "esbuild-darwin-64" could not be found, and is needed by esbuild.
 
 

js 유틸리티 함수

export function getFaunaError (error) {

  const {code, description} = error.requestResult.responseContent.errors[0];
  let status;

  switch (code) {
    case 'instance not found':
      status = 404;
      break;
    case 'instance not unique':
      status = 409;
      break;
    case 'permission denied':
      status = 403;
      break;
    case 'unauthorized':
    case 'authentication failed':
      status = 401;
      break;
    default:
      status = 500;
  }

  return {code, description, status};
}
fuana 에러처리용 유틸리티 함수를 utils.js 파일에 추가합니다.
 

product 생성 로직

index.js
import faunadb from 'faunadb'
import { Router } from 'itty-router'
import { getFaunaError } from './utils'

const router = Router()

const faunaClient = new faunadb.Client({
  secret: FAUNA_SECRET,
})

const { Create, Collection } = faunadb.query

router.post('/products', async req => {
  try {
    const { serialNumber, title, weightLbs } = await req.json()

    const result = await faunaClient.query(
      Create(Collection('Products'), {
        data: {
          serialNumber,
          title,
          weightLbs,
          quantity: 0,
        },
      }),
    )

    return new Response(
      JSON.stringify({
        productId: result.ref.id,
      }),
    )
  } catch (error) {
    const faunaError = getFaunaError(error)
    return new Response(JSON.stringify(faunaError), {
      status: faunaError.status,
    })
  }
})

router.get('/', () => new Response('hello'))

addEventListener('fetch', event => {
  event.respondWith(router.handle(event.request))
})
faunaClient 연결이 매우 간단하네요
 
 
notion image
생성된 product 확인
 
 

product 조회 로직 작성

router.get('/products/:productId', async req => {
  try {
    const { productId } = req.params

    const result = await faunaClient.query(
      Get(Ref(Collection('Products'), productId)),
    )

    return new Response(JSON.stringify(result))
  } catch (error) {
    console.log(error)
    const faunaError = getFaunaError(error)

    return new Response(JSON.stringify(faunaError), {
      status: faunaError.status,
    })
  }
})
Get 조회 쿼리로 동일 productId의 문서를 찾습니다.
 
 
notion image
조회 성공 결과
 
 
 
const start = Date.now()

const result = await faunaClient.query(
  Get(Ref(Collection('Products'), productId)),
)

const time = Date.now() - start
위 조회 로직에서 디비에 접근하기 전 후 타이머로 재보니 100~200ms 내외로 끝나네요.
서버리스 함수 전체로는 200~500ms 정도 걸립니다.
이정도면 나쁘지 않은 것 같습니다.
 
update, delete는 생략합니다.
 

단점

FQL 문법이 생소하다..
 
 
 

Loading Comments...