Skip to content

Cloudflare Workers에서 Prisma 사용하기 ​

Cloudflare Workers에서 Prisma를 사용하는 방법은 두 가지가 있다. Prisma Accelerate를 사용하는 방법과 Driver Adapter를 사용하는 방법이다.

Prisma Accelerate 사용하기 ​

Prisma 설치 ​

Hono Cloudflare Workers에 Prisma를 설치한다. 여기서는 neon.tech의 무료 티어를 PostgreSQL 데이터베이스로 사용하지만, 프로젝트에 적합한 데이터베이스를 선택할 수 있다.

neon.tech로 이동해 무료 PostgreSQL 데이터베이스를 생성한다.

bash
npm i prisma --save-dev
npx prisma init

Prisma Accelerate 설정하기 ​

Accelerate를 설정하려면 Prisma Accelerate로 이동해 무료로 로그인하거나 등록한다.

로그인하면 새로운 Accelerate 프로젝트를 생성할 수 있는 페이지로 이동한다.

Accelerate Page

New project 버튼을 클릭해 새 프로젝트를 생성하고, 프로젝트 이름을 지정한다.

Accelerate Page

그러면 아래와 같은 페이지로 이동한다:

Accelerate Edit Page

Enable Accelerate 버튼을 클릭하면 다음 페이지로 이동한다:

Enable Page

neon.tech 데이터베이스 연결 문자열을 database connection string 필드에 붙여넣고, 리전을 선택한 후 Enable Accelerate 버튼을 클릭한다.

다음과 같은 화면이 나타난다:

API Key

Generate API Key를 클릭하면 아래와 같은 새로운 API 키를 받을 수 있다:

bash
DATABASE_URL="prisma://accelerate...."

이 DATABASE_URL을 복사해 .dev.vars와 .env 파일에 저장한다. 나중에 Prisma CLI가 이 값을 사용할 수 있도록 하기 위함이다.

프로젝트에 Prisma 설정하기 ​

neon.tech에서 받은 URL은 Prisma에 더 많은 옵션을 제공할 수 있는 대체 URL로 사용할 수 있다. 나중에 사용할 수 있도록 저장해두자:

bash
DATABASE_URL="your_prisma_accelerate_url"
DIRECT_URL="your_neon_tech_url"

이제 schema.prisma 파일로 이동해 다음과 같이 URL을 설정한다:

ts
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}

프로젝트에서 나중에 사용할 수 있는 함수를 다음과 같이 만든다:

ts
import { PrismaClient } from '@prisma/client/edge'
import { withAccelerate } from '@prisma/extension-accelerate'

export const getPrisma = (database_url: string) => {
  const prisma = new PrismaClient({
    datasourceUrl: database_url,
  }).$extends(withAccelerate())
  return prisma
}

이 함수를 프로젝트에서 어떻게 사용할 수 있는지 예제를 살펴보자:

ts
import { Hono } from 'hono'
import { sign, verify } from 'hono/jwt'
import { getPrisma } from '../usefulFun/prismaFun'

// Hono 앱 생성
const app = new Hono<{
  Bindings: {
    DATABASE_URL: string
    JWT_SECRET: string
  }
  Variables: {
    userId: string
  }
}>()

app.post('/', async (c) => {
  // 원하는 곳에서 사용 가능
  const prisma = getPrisma(c.env.DATABASE_URL)
})

Prisma Driver Adapter 사용하기 ​

Prisma는 driverAdapters를 통해 D1 Database와 함께 사용할 수 있다. 이를 위해서는 Prisma를 설치하고 Wrangler를 통합해 Hono 프로젝트와 바인딩해야 한다. Hono, Prisma, D1 Cloudflare에 대한 모든 문서가 분리되어 있고 정확한 단계별 지침이 없기 때문에, 이는 예제 프로젝트로 제공된다.

Prisma 설정하기 ​

Prisma와 D1은 Wrangler의 바인딩을 사용해 어댑터와의 연결을 보안 처리한다.

bash
npm install prisma --save-dev
npx prisma init
npm install @prisma/client
npm install @prisma/adapter-d1

이 과정을 마치면 Prisma가 데이터베이스 스키마를 생성한다. prisma/schema.prisma 파일에 간단한 모델을 정의한다. 어댑터를 변경하는 것을 잊지 말아야 한다.

prisma/schema.prisma
typescript
generator client {
  provider        = "prisma-client-js"
  previewFeatures = ["driverAdapters"] // 기본값에서 변경
}

datasource db {
  provider = "sqlite" // D1은 SQL 기반 데이터베이스
  url      = env("DATABASE_URL")
}

// 간단한 데이터베이스 모델 생성
model User {
  id    String @id  @default(uuid())
  email String  @unique
  name  String?
}

D1 데이터베이스 ​

이미 D1 데이터베이스가 준비되어 있다면 이 단계를 건너뛰어도 된다. 그렇지 않다면, 여기에서 리소스를 생성할 수 있다.

bash
npx wrangler d1 create __DATABASE_NAME__ // 자신의 데이터베이스 이름으로 변경

wrangler.toml 파일에서 데이터베이스 바인딩이 제대로 설정되었는지 확인한다.

wrangler.toml
toml
[[d1_databases]]
binding = "DB" # 예: Worker에서 env.DB로 접근 가능
database_name = "__DATABASE_NAME__"
database_id = "DATABASE ID"

Prisma Migrate ​

이 커맨드는 Prisma를 마이그레이션하고 로컬 또는 원격 D1 데이터베이스로 변경한다.

bash
npx wrangler d1 migrations create __DATABASE_NAME__ create_user_table # 마이그레이션 폴더와 sql 파일을 생성

// SQL 문을 생성하기 위해

npx prisma migrate diff \
  --from-empty \
  --to-schema-datamodel ./prisma/schema.prisma \
  --script \
  --output migrations/0001_create_user_table.sql

데이터베이스 모델을 D1으로 마이그레이션한다.

bash
npx wrangler d1 migrations apply __DATABASE_NAME__ --local
npx wrangler d1 migrations apply __DATABASE_NAME__ --remote
npx prisma generate

Prisma 클라이언트 설정 ​

D1 데이터베이스를 사용해 Prisma로 데이터베이스를 쿼리하려면 타입을 추가해야 한다. 다음 명령어를 사용한다:

bash
npx wrangler types

이 명령어는 worker-configuration.d.ts 파일을 생성한다.

Prisma 클라이언트 ​

Prisma를 전역적으로 사용하려면 lib/prismaClient.ts 파일을 만들고 다음과 같은 코드를 작성한다.

ts
import { PrismaClient } from '@prisma/client'
import { PrismaD1 } from '@prisma/adapter-d1'

const prismaClients = {
  async fetch(db: D1Database) {
    const adapter = new PrismaD1(db)
    const prisma = new PrismaClient({ adapter })
    return prisma
  },
}

export default prismaClients

Hono를 Wrangler 환경 값과 바인딩하는 방법:

ts
import { Hono } from 'hono'
import prismaClients from '../lib/prismaClient'

type Bindings = {
  MY_KV: KVNamespace
  DB: D1Database
}

const app = new Hono<{ Bindings: Bindings }>() // 환경 값 바인딩

Hono 라우트에서 사용하는 예제:

ts
import { Hono } from 'hono'
import prismaClients from '../lib/prismaClient'

type Bindings = {
  MY_KV: KVNamespace
  DB: D1Database
}
const app = new Hono<{ Bindings: Bindings }>()

app.get('/', async (c) => {
  const prisma = await prismaClients.fetch(c.env.DB)
  const users = await prisma.user.findMany()
  console.log('users', users)
  return c.json(users)
})

export default app

이 코드는 / 라우트에서 모든 사용자를 반환한다. 결과를 확인하려면 Postman이나 Thunder Client를 사용한다.

Released under the MIT License.