로컬 개발 (Local development)
D1은 로컬 개발을 완벽하게 지원하며, Cloudflare가 전 세계에서 실행하는 것과 같은 버전의 D1을 실행해요. 로컬 개발은 Workers용 명령줄 인터페이스인 Wrangler를 사용해 로컬 개발 세션과 상태를 관리해요.
출처: 문서
본문
로컬 개발 세션 시작하기
참고
이 가이드는 Wrangler v3.0 ↗︎ 이상을 사용한다고 가정해요.
D1 및/또는 Cloudflare Workers가 처음이라면 D1 튜토리얼을 방문해서 wrangler를 설치하고 첫 데이터베이스를 배포해 보세요.
로컬 개발 세션은 D1이 실행되는 프로덕션 환경을 그대로 반영하는 독립적이고 로컬 전용 환경을 만들어서, 프로덕션에 배포하기 전에 Worker와 D1을 테스트할 수 있게 해 줘요.
로컬에서 실행할 때 Worker에는 기존의 DB D1 바인딩이 제공돼요.
로컬 개발 세션을 시작하려면:
-
wrangler v3.0+를 사용 중인지 확인하세요.
wrangler --version⛅️ wrangler 3.0.0 -
로컬 개발 세션을 시작하세요.
wrangler dev------------------ wrangler dev now uses local mode by default, powered by 🔥 Miniflare and 👷 workerd. To run an edge preview session for your Worker, use wrangler dev --remote Your worker has access to the following bindings: - D1 Databases: - DB: test-db (c020574a-5623-407b-be0c-cd192bab9545) ⎔ Starting local server... [mf:inf] Ready on http://127.0.0.1:8787/ [b] open a browser, [d] open Devtools, [l] turn off local mode, [c] clear console, [x] to exit
이 예시에서 Worker는 로컬 전용 D1 데이터베이스에 접근할 수 있어요. Wrangler 설정 파일의 해당 D1 바인딩은 다음과 같아요.
{
"d1_databases": [
{
"binding": "DB",
"database_name": "test-db",
"database_id": "c020574a-5623-407b-be0c-cd192bab9545"
}
]
}
[[d1_databases]]
binding = "DB"
database_name = "test-db"
database_id = "c020574a-5623-407b-be0c-cd192bab9545"
wrangler dev는 로컬 데이터와 프로덕션(원격) 데이터를 분리한다는 점에 주의하세요. 로컬 세션은 기본적으로 프로덕션 데이터에 접근할 수 없어요. 프로덕션(원격) 데이터베이스에 접근하려면 D1 바인딩 설정에서 "remote" : true를 설정하세요. 자세한 내용은 원격 바인딩 문서를 참고하세요. 원격 데이터베이스에 대해 실행하면서 변경한 내용은 되돌릴 수 없어요.
로컬 개발 세션을 구성하는 방법을 더 배우려면 wrangler dev 문서를 참고하세요.
Pages로 로컬 개발하기
Cloudflare Pages를 사용할 때는 Pages 프로젝트의 루트에 최소한의 Wrangler 설정 파일을 만들어야 로컬 D1 데이터베이스에 대해서만 개발할 수 있어요. 이는 애플리케이션 로직에 추가하지 않고, 스키마를 만들거나 데이터를 시딩하거나 D1 데이터베이스를 직접 관리할 때 유용해요.
원격 데이터베이스에 대한 로컬 개발
Cloudflare Pages를 사용할 때 원격 D1 데이터베이스에 대해 개발하는 것은 현재 불가능해요.
Wrangler 설정 파일은 다음과 같아야 해요.
{
// If you are only using Pages + D1, you only need the below in your Wrangler config file to interact with D1 locally.
"d1_databases": [
{
"binding": "DB", // Should match preview_database_id
"database_name": "YOUR_DATABASE_NAME",
"database_id": "the-id-of-your-D1-database-goes-here", // wrangler d1 info YOUR_DATABASE_NAME
"preview_database_id": "DB" // Required for Pages local development
}
]
}
[[d1_databases]]
binding = "DB"
database_name = "YOUR_DATABASE_NAME"
database_id = "the-id-of-your-D1-database-goes-here"
preview_database_id = "DB"
그런 다음 로컬 개발 과정의 일부로 wrangler에 --local 플래그를 전달해서 로컬 데이터베이스에 대해 쿼리를 실행하거나 마이그레이션을 실행할 수 있어요.
wrangler d1 execute YOUR_DATABASE_NAME \
--local --command "CREATE TABLE IF NOT EXISTS users ( user_id INTEGER PRIMARY KEY, email_address TEXT, created_at INTEGER, deleted INTEGER, settings TEXT);"
위 명령은 D1 데이터베이스의 로컬 전용 버전에 대해 쿼리를 실행해요. --local 플래그가 없으면 명령은 Cloudflare 네트워크에서 실행되는 D1 데이터베이스의 원격 버전에 대해 실행돼요.
데이터 유지하기 (Persist data)
참고
기본적으로 Wrangler v3 이상에서는 wrangler dev를 실행할 때마다 데이터가 유지돼요. 로컬 개발과 테스트가 빈 데이터베이스를 요구하거나 가정한다면, CREATE TABLE로 테이블을 다시 만들기 전에 DROP TABLE <tablename> 구문으로 기존 테이블을 삭제하는 것부터 시작해야 해요.
wrangler dev --persist-to=/path/to/file을 사용해 데이터를 특정 위치에 유지하세요. 이는 팀에서 작업할 때(같은 복사본을 공유할 수 있게), CI/CD로 배포할 때(같은 시작 상태를 보장하기 위해), 또는 머신 간에 마이그레이션할 때 데이터를 유지하는 방법으로 유용해요.
wrangler 2.x 사용자는 --persist 플래그를 사용해야 해요. 이전 버전의 wrangler는 기본적으로 데이터를 유지하지 않았어요.
프로그래밍 방식으로 테스트하기
Miniflare
Miniflare ↗︎를 사용하면 프로덕션에서 사용되는 것과 같은 기본 런타임과 코드를 사용해 Workers와 D1 같은 리소스를 시뮬레이션할 수 있어요.
Miniflare의 D1 지원 ↗︎을 사용해 테스트에 사용할 D1 데이터베이스를 만들 수 있어요.
{
"d1_databases": [
{
"binding": "DB",
"database_name": "test-db",
"database_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
]
}
[[d1_databases]]
binding = "DB"
database_name = "test-db"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
const mf = new Miniflare({
d1Databases: {
DB: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
},
});
그런 다음 getD1Database() 메서드를 사용해 시뮬레이션된 데이터베이스를 검색하고, 마치 실제 프로덕션 D1 데이터베이스인 것처럼 쿼리를 실행할 수 있어요.
const db = await mf.getD1Database("DB");
const stmt = db.prepare("SELECT name, age FROM users LIMIT 3");
const { results } = await stmt.run();
console.log(results);
unstable_dev
Wrangler는 Workers와 D1을 테스트하기 위한 로컬 HTTP 서버를 실행할 수 있게 해 주는 unstable_dev()를 노출해요. Wrangler 설정에 preview_database_id를 설정해서 로컬 데이터베이스에 대해 마이그레이션(migrations)을 실행하세요.
아래와 같은 Wrangler 설정이 있다고 가정할 때:
{
"d1_databases": [
{
"binding": "DB", // i.e. if you set this to "DB", it will be available in your Worker at `env.DB`
"database_name": "your-database", // the name of your D1 database, set when created
"database_id": "<UUID>", // The unique ID of your D1 database, returned when you create your database or run `
"preview_database_id": "local-test-db" // A user-defined ID for your local test database.
}
]
}
[[d1_databases]]
binding = "DB"
database_name = "your-database"
database_id = "<UUID>"
preview_database_id = "local-test-db"
CI/CD 셋업의 일부로 wrangler에 --local 플래그를 전달해서 마이그레이션을 로컬에서 실행할 수 있어요.
wrangler d1 migrations apply your-database --local
사용 예시
다음 예시는 Wrangler의 unstable_dev() API를 사용하는 방법을 보여 줘요.
preview_database_id로 정의된 로컬 테스트 데이터베이스에 대해 마이그레이션을 실행해요.- Worker에 정의된 엔드포인트에 요청을 보내요. 이 예시는
/api/users/?limit=2를 사용해요. - 반환된 결과가 일치하는지 검증해요. 여기에는
Response.status와 API가 반환하는 JSON이 포함돼요.
import { unstable_dev } from "wrangler";
import type { UnstableDevWorker } from "wrangler";
describe("Test D1 Worker endpoint", () => {
let worker: UnstableDevWorker;
beforeAll(async () => {
// Optional: Run any migrations to set up your `--local` database
// By default, this will default to the preview_database_id
execSync(`NO_D1_WARNING=true wrangler d1 migrations apply db --local`);
worker = await unstable_dev("src/index.ts", {
experimental: { disableExperimentalWarning: true },
});
});
afterAll(async () => {
await worker.stop();
});
it("should return an array of users", async () => {
// Our expected results
const expectedResults = `{"results": [{"user_id": 1234, "email": "foo@example.com"},{"user_id": 6789, "email": "bar@example.com"}]}`;
// Pass an optional URL to fetch to trigger any routing within your Worker
const resp = await worker.fetch("/api/users/?limit=2");
if (resp) {
// https://jestjs.io/docs/expect#tobevalue
expect(resp.status).toBe(200);
const data = await resp.json();
// https://jestjs.io/docs/expect#tomatchobjectobject
expect(data).toMatchObject(expectedResults);
}
});
});
테스트 안에서 이 API를 사용하는 방법에 대한 더 자세한 내용은 unstable_dev() 문서를 참고하세요.
관련 리소스 (Related resources)
wrangler dev를 사용해 배포 전에 Worker와 D1을 로컬에서 실행하고 문제를 디버깅하세요.- D1을 디버깅하는 방법을 배워 보세요.
- Worker와 D1에서 생성된 로그에 접근하는 방법을 이해해 보세요.