Supabase Edge Functions와 함께 Drizzle 사용하기
이 튜토리얼은 Supabase Edge Functions에서 Drizzle ORM을 사용하는 방법을 보여줍니다.
- 최신 버전의 Supabase CLI가 설치되어 있어야 합니다.
- Drizzle ORM과 Drizzle kit이 설치되어 있어야 합니다. 다음 명령어로 설치할 수 있습니다:
npm i drizzle-orm
npm i -D drizzle-kit
- Docker Desktop이 설치되어 있어야 합니다. 로컬 개발을 위한 필수 요구사항입니다. 공식 문서를 참조하여 설치하세요.
로컬 환경에서 기본적인 Edge Function을 생성하고 배포하는 방법을 알아보려면 Edge Functions 빠른 시작을 참조하세요.
테이블 생성
src 디렉토리에 schema.ts 파일을 생성하고 테이블 스키마를 선언합니다:
import { pgTable, serial, text, integer } from "drizzle-orm/pg-core";
export const usersTable = pgTable('users_table', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
age: integer('age').notNull()
})이 파일은 데이터베이스 마이그레이션을 생성하는 데 사용됩니다.
Drizzle 설정 파일 구성
Drizzle config - Drizzle Kit에서 사용하는 설정 파일로, 데이터베이스 연결, 마이그레이션 폴더, 스키마 파일에 대한 모든 정보를 포함합니다.
프로젝트 루트에 drizzle.config.ts 파일을 생성하고 다음 내용을 추가합니다:
import { defineConfig } from "drizzle-kit";
export default defineConfig({
schema: "./src/schema.ts",
out: "./supabase/migrations",
dialect: "postgresql",
});이 튜토리얼에서는 Drizzle kit을 사용하여 스키마에 대한 마이그레이션을 생성합니다.
새로운 Supabase 프로젝트 초기화
로컬 환경의 폴더에서 새로운 Supabase 프로젝트를 생성합니다:
supabase init이 명령어는 config.toml 파일이 포함된 supabase 폴더를 생성합니다:
└── supabase
└── config.tomlVisual Studio Code를 사용하는 경우 Supabase 문서를 참조하여 Deno 설정을 구성하세요.
마이그레이션 생성
drizzle-kit generate 명령어를 실행하여 마이그레이션을 생성합니다:
npx drizzle-kit generate이 명령어는 supabase/migrations 디렉토리에 새로운 마이그레이션 파일을 생성합니다:
마이그레이션 적용
Supabase 로컬 개발 스택을 시작하려면 다음 명령어를 실행합니다:
supabase start마이그레이션을 적용하려면 다음 명령어를 실행합니다:
supabase migration upSupabase 마이그레이션에 대한 자세한 내용은 문서를 참조하세요.
또는 drizzle-kit migrate 명령어를 사용하여 마이그레이션을 적용할 수도 있습니다. 이 마이그레이션 프로세스에 대한 자세한 내용은 문서를 참조하세요.
새로운 Edge Function 생성
supabase functions new [FUNCTION_NAME] 명령어를 실행하여 새로운 Edge Function을 생성합니다:
supabase functions new drizzle-tutorial이 명령어는 supabase/functions 디렉토리에 함수 이름의 새로운 폴더를 생성합니다:
└── supabase
└── functions
│ └── drizzle-tutorial
│ │ ├── .npmrc ## Function-specific npm configuration (if needed)
│ │ ├── deno.json ## Function-specific Deno configuration
│ │ └── index.ts ## Your function code새로운 Edge Function을 생성하면 기본적으로 TypeScript를 사용합니다. 하지만 JavaScript로 Edge Function을 작성하는 것도 가능합니다. 자세한 내용은 문서를 참조하세요.
imports 설정
supabase/functions/drizzle-tutorial 디렉토리의 deno.json 파일에 다음 imports를 추가합니다:
{
"imports": {
"drizzle-orm/": "npm:/drizzle-orm/",
"postgres": "npm:postgres"
}
}종속성 관리에 대한 자세한 내용은 여기를 참조하세요.
functions 디렉토리에 스키마 복사
src/schema.ts 파일에서 edge function에 사용할 코드를 supabase/functions/drizzle-tutorial/index.ts 파일로 복사합니다:
// Setup type definitions for built-in Supabase Runtime APIs
import "jsr:@supabase/functions-js/edge-runtime.d.ts"
import { pgTable, serial, text, integer } from "drizzle-orm/pg-core";
const usersTable = pgTable('users_table', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
age: integer('age').notNull()
})
Deno.serve(async (req) => {
const { name } = await req.json()
const data = {
message: `Hello ${name}!`,
}
return new Response(
JSON.stringify(data),
{ headers: { "Content-Type": "application/json" } },
)
})Deno 생태계에서는 각 함수를 고유한 종속성과 구성을 가진 독립적인 프로젝트로 취급해야 합니다.
이러한 이유로 Supabase는 일부 구성이 중복되더라도 각 함수 디렉토리 내에 별도의 구성 파일(deno.json, .npmrc 또는 import_map.json)을 유지할 것을 권장합니다. 자세한 내용은 여기를 참조하세요.
Drizzle ORM을 데이터베이스에 연결
데이터베이스 구성으로 edge function 코드를 업데이트합니다:
// Setup type definitions for built-in Supabase Runtime APIs
import { integer, pgTable, serial, text } from "drizzle-orm/pg-core";
import { drizzle } from "drizzle-orm/postgres-js";
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import postgres from "postgres";
const usersTable = pgTable('users_table', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
age: integer('age').notNull()
})
Deno.serve(async () => {
const connectionString = Deno.env.get("SUPABASE_DB_URL")!;
// Disable prefetch as it is not supported for "Transaction" pool mode
const client = postgres(connectionString, { prepare: false });
const db = drizzle({ client });
await db.insert(usersTable).values({
name: "Alice",
age: 25
})
const data = await db.select().from(usersTable);
return new Response(
JSON.stringify(data)
)
})SUPABASE_DB_URL은 직접 데이터베이스 연결을 위한 기본 환경 변수입니다. Supabase Edge Functions에서 환경 변수 관리에 대한 자세한 내용은 문서를 참조하세요.
로컬에서 코드 테스트
다음 명령어를 실행하여 함수를 로컬에서 테스트합니다:
supabase functions serve --no-verify-jwt브라우저에서 라우트 (예: /drizzle-tutorial)로 이동합니다:
[
{
"id": 1,
"name": "Alice",
"age": 25
}
]로컬 프로젝트를 호스팅된 Supabase 프로젝트에 연결
대시보드에서 또는 이 링크를 통해 새로운 Supabase 프로젝트를 생성할 수 있습니다.
프로젝트 설정에서 Reference ID를 복사하고 다음 명령어를 실행하여 로컬 개발 프로젝트를 호스팅된 Supabase 프로젝트에 연결합니다:
supabase link --project-ref=<REFERENCE_ID>다음 명령어를 실행하여 스키마 변경 사항을 호스팅된 Supabase 프로젝트에 푸시합니다:
supabase db push환경 변수 설정
대시보드 상단의 Connect를 클릭하여 Project connect details를 찾고, Transaction pooler 섹션에서 URI를 복사합니다. 비밀번호 플레이스홀더를 실제 데이터베이스 비밀번호로 교체해야 합니다.
Connection Pooler에 대한 자세한 내용은 문서를 참조하세요.
SUPABASE_DB_URL 대신 DATABASE_URL 환경 변수를 사용하도록 edge function 코드를 업데이트합니다:
// imports
// const connectionString = Deno.env.get("SUPABASE_DB_URL")!;
const connectionString = Deno.env.get("DATABASE_URL")!;
// code다음 명령어를 실행하여 환경 변수를 설정합니다:
supabase secrets set DATABASE_URL=<CONNECTION_STRING>Supabase Edge Functions에서 환경 변수 관리에 대한 자세한 내용은 문서를 참조하세요.
함수 배포
다음 명령어를 실행하여 함수를 배포합니다:
supabase functions deploy drizzle-tutorial --no-verify-jwt마지막으로, 배포된 프로젝트의 URL을 사용하고 생성한 라우트 (예: /drizzle-tutorial)로 이동하여 edge function에 접근할 수 있습니다.