From 5e686c0a9ab233e69ece5485184ae0e8befca37b Mon Sep 17 00:00:00 2001 From: conico974 Date: Fri, 2 May 2025 14:58:36 +0200 Subject: [PATCH 1/4] added some docs for prisma and drizzle --- pages/cloudflare/howtos/_meta.json | 3 +- pages/cloudflare/howtos/db.mdx | 216 +++++++++++++++++++++++++++++ 2 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 pages/cloudflare/howtos/db.mdx diff --git a/pages/cloudflare/howtos/_meta.json b/pages/cloudflare/howtos/_meta.json index 2c781b5..9ea268d 100644 --- a/pages/cloudflare/howtos/_meta.json +++ b/pages/cloudflare/howtos/_meta.json @@ -1,9 +1,10 @@ { "NextAuth": "NextAuth", "stripeAPI": "Stripe API", + "db": "Database", "dev-deploy": "Develop and Deploy", "env-vars": "Environment Variables", "image": "Image Optimization", "custom-worker": "Custom Worker", "keep_names": "__name issues" -} +} \ No newline at end of file diff --git a/pages/cloudflare/howtos/db.mdx b/pages/cloudflare/howtos/db.mdx new file mode 100644 index 0000000..9f601a5 --- /dev/null +++ b/pages/cloudflare/howtos/db.mdx @@ -0,0 +1,216 @@ +This page will show you how to setup some popular database ORM libraries to use in OpenNext. There are some subtleties to be aware of when using these libraries in Cloudflare Workers, so we will cover those here. + +If you encounter issue with a specific library, please open an issue on the [OpenNext GitHub repository](https://github.com/opennextjs/opennextjs-cloudflare/issues). + + +## Drizzle +Drizzle is a TypeScript ORM for SQL databases. It is designed to be lightweight and easy to use, making it a great choice for Cloudflare Workers. +There is not much specific to configure in drizzle, but there is one important thing to note is that you don't want to have a global client. + +### `lib/db.ts` +Instead of creating a global client, you should create a new client for each request. This is because some adapters (like Postgres) will use a connection pool, and reuse the same connection for multiple requests. This is not allowed in Cloudflare Workers, and will cause subsequent requests to fail. + +#### PostgreSQL + +Instead of that : +```ts +//lib/db.ts +import { drizzle } from 'drizzle-orm/node-postgres'; +import * as schema from './schema/pg'; +import { Pool } from 'pg'; + +const pool = new Pool({ + connectionString: process.env.PG_URL, +}) +export const db = drizzle({client: pool, schema}) +``` + +You should do this instead: + +```ts +//lib/db.ts +import { drizzle } from 'drizzle-orm/node-postgres'; +// You can use cache from react to cache the client during the same request +// this is not mandatory and only has an effect for server components +import { cache } from 'react'; +import * as schema from './schema/pg'; +import { Pool } from 'pg'; + +export const getDb = cache(() => { + const pool = new Pool({ + // This env could be set either in the .env file or in wrangler.jsonc + connectionString: process.env.PG_URL, + // You don't want to reuse the same connection for multiple requests + maxUses: 1, + }) + return drizzle({client: pool, schema}) +}) +``` + +#### D1 example +```ts +import { getCloudflareContext } from '@opennextjs/cloudflare'; +import { drizzle } from 'drizzle-orm/d1'; +import { cache } from 'react'; +import * as schema from './schema/d1'; + +export const getDb = cache(() => { + const {env} = getCloudflareContext() + return drizzle(env.MY_D1, {schema}) +}) + +// This is the one to use for static routes (i.e. ISR/SSG) +export const getDbAsync = cache(async () => { + const {env} = await getCloudflareContext({async: true}) + return drizzle(env.MY_D1, {schema}) +}) +``` + +#### Hyperdrive example +```ts +import { getCloudflareContext } from '@opennextjs/cloudflare'; +import { drizzle } from 'drizzle-orm/node-postgres'; +import { cache } from 'react'; +import * as schema from './schema/pg'; +import { Pool } from 'pg'; + +export const getDb = cache(() => { + const {env} = getCloudflareContext() + const connectionString = env.HYPERDRIVE.connectionString + const pool = new Pool({ + // This env could be set either in the .env file or in wrangler.jsonc + connectionString: process.env.PG_URL, + // You don't want to reuse the same connection for multiple requests + maxUses: 1, + }) + return drizzle({client: pool, schema}) +}) + +// This is the one to use for static routes (i.e. ISR/SSG) +export const getDbAsync = cache(async () => { + const {env} = await getCloudflareContext({async: true}) + const connectionString = env.HYPERDRIVE.connectionString + const pool = new Pool({ + // This env could be set either in the .env file or in wrangler.jsonc + connectionString: process.env.PG_URL, + // You don't want to reuse the same connection for multiple requests + maxUses: 1, + }) + return drizzle({client: pool, schema}) +}) +``` + +You can then use the `getDb` function to get a new client for each request. This will ensure that you don't run into any issues with connection pooling. + +## Prisma +Prisma is a popular ORM for Node.js and TypeScript. It is designed to be easy to use and provides a lot of features out of the box. However, there are some subtleties to be aware of when using Prisma in Cloudflare Workers. + +### `schema.prisma` +When using prisma in OpenNext, you do not want to provide an output directory for the generated client. +```prisma +generator client { + provider = "prisma-client-js" + previewFeatures = ["driverAdapters"] +} +``` +This is because the generated client needs to be patched by OpenNext to work with Cloudflare Workers. If you provide an output directory, OpenNext will not be able to patch the client and it will not work. + +### `next.config.ts` +Because prisma has some specific exports for cloudflare workers, you need to add the following to your `next.config.ts` file: +```ts +const nextConfig: NextConfig = { + serverExternalPackages: [ + "@prisma/client", + ".prisma/client", + ] +}; +``` +By doing this, this will ensure that both the generated client and the prisma client are included in the build for the correct runtime. + +### `lib/db.ts` +Instead of creating a global client, you should create a new client for each request. This is because some adapters (like Postgres) will use a connection pool, and reuse the same connection for multiple requests. This is not allowed in Cloudflare Workers, and will cause subsequent requests to fail. + +#### D1 example + +Instead of that : +```ts +//lib/db.ts +import { getCloudflareContext } from "@opennextjs/cloudflare"; +import { PrismaClient } from '@prisma/client'; +import { PrismaD1 } from '@prisma/adapter-d1' + +const { env } = getCloudflareContext(); +const adapter = new PrismaD1(env.MY_D1) +export const db = new PrismaClient() +``` +You should do this instead: + +```ts +//lib/db.ts +import { getCloudflareContext } from "@opennextjs/cloudflare"; +// You can use cache from react to cache the client during the same request +// this is not mandatory and only has an effect for server components +import { cache } from "react"; +import { PrismaClient } from '@prisma/client'; +import { PrismaD1 } from '@prisma/adapter-d1' + +export const getDb = cache(() => { + const { env } = getCloudflareContext(); + const adapter = new PrismaD1(env.MY_D1) + return new PrismaClient({ adapter }) +}) + +// If you need access to `getCloudflareContext` in a static route (i.e. ISR/SSG), you should use the async version of `getCloudflareContext` to get the context. +export const getDbAsync = async () => { + const { env } = await getCloudflareContext({async : true}); + const adapter = new PrismaD1(env.MY_D1) + const prisma = new PrismaClient({ adapter }) + return prisma +} +``` +You can then use the `getDb` function to get a new client for each request. This will ensure that you don't run into any issues with connection pooling. + +#### PostgreSQL +You can also use Prisma with PostgreSQL. The setup is similar to the D1 setup above, but you need to use the `PrismaPostgres` adapter instead of the `PrismaD1` adapter. + +```ts +import { cache } from "react"; +import { PrismaClient } from '@prisma/client'; +import { PrismaPg } from '@prisma/adapter-pg' + +export const getDb = cache(() => { + const connectionString = process.env.PG_URL ?? "" + const adapter = new PrismaPg({connectionString, maxUses: 1}) + const prisma = new PrismaClient({ adapter }) + return prisma +}) +``` +You can then use the `getDb` function to get a new client for each request. This will ensure that you don't run into any issues with connection pooling. + +#### Hyperdrive +You can also use Prisma with Hyperdrive. The setup is similar to the PostgreSQL setup above. +```ts +//lib/db.ts +import { getCloudflareContext } from "@opennextjs/cloudflare"; +// You can use cache from react to cache the client during the same request +// this is not mandatory and only has an effect for server components +import { cache } from "react"; +import { PrismaClient } from '@prisma/client'; +import { PrismaPg } from '@prisma/adapter-pg' + + +export const getDb = cache(() => { + const { env } = getCloudflareContext(); + const connectionString = env.HYPERDRIVE.connectionString; + const adapter = new PrismaPg({connectionString, maxUses: 1}) + return new PrismaClient({ adapter }) +}) + +// This is the one to use for static routes (i.e. ISR/SSG) +export const getDbAsync = async () => { + const { env } = await getCloudflareContext({async : true}); + const connectionString = env.HYPERDRIVE.connectionString; + const adapter = new PrismaPg({connectionString, maxUses: 1}) + return new PrismaClient({ adapter }) +} +``` \ No newline at end of file From 3874e3c155dd1abf0b86846af4fe500bcdbce0e4 Mon Sep 17 00:00:00 2001 From: conico974 Date: Fri, 2 May 2025 15:06:39 +0200 Subject: [PATCH 2/4] lint fix --- pages/cloudflare/howtos/_meta.json | 2 +- pages/cloudflare/howtos/db.mdx | 207 ++++++++++++++++------------- 2 files changed, 112 insertions(+), 97 deletions(-) diff --git a/pages/cloudflare/howtos/_meta.json b/pages/cloudflare/howtos/_meta.json index 9ea268d..1a2aa5d 100644 --- a/pages/cloudflare/howtos/_meta.json +++ b/pages/cloudflare/howtos/_meta.json @@ -7,4 +7,4 @@ "image": "Image Optimization", "custom-worker": "Custom Worker", "keep_names": "__name issues" -} \ No newline at end of file +} diff --git a/pages/cloudflare/howtos/db.mdx b/pages/cloudflare/howtos/db.mdx index 9f601a5..24c4f2d 100644 --- a/pages/cloudflare/howtos/db.mdx +++ b/pages/cloudflare/howtos/db.mdx @@ -2,147 +2,158 @@ This page will show you how to setup some popular database ORM libraries to use If you encounter issue with a specific library, please open an issue on the [OpenNext GitHub repository](https://github.com/opennextjs/opennextjs-cloudflare/issues). - ## Drizzle + Drizzle is a TypeScript ORM for SQL databases. It is designed to be lightweight and easy to use, making it a great choice for Cloudflare Workers. There is not much specific to configure in drizzle, but there is one important thing to note is that you don't want to have a global client. ### `lib/db.ts` + Instead of creating a global client, you should create a new client for each request. This is because some adapters (like Postgres) will use a connection pool, and reuse the same connection for multiple requests. This is not allowed in Cloudflare Workers, and will cause subsequent requests to fail. #### PostgreSQL -Instead of that : +Instead of that : + ```ts //lib/db.ts -import { drizzle } from 'drizzle-orm/node-postgres'; -import * as schema from './schema/pg'; -import { Pool } from 'pg'; +import { drizzle } from "drizzle-orm/node-postgres"; +import * as schema from "./schema/pg"; +import { Pool } from "pg"; const pool = new Pool({ connectionString: process.env.PG_URL, -}) -export const db = drizzle({client: pool, schema}) +}); +export const db = drizzle({ client: pool, schema }); ``` You should do this instead: ```ts //lib/db.ts -import { drizzle } from 'drizzle-orm/node-postgres'; +import { drizzle } from "drizzle-orm/node-postgres"; // You can use cache from react to cache the client during the same request // this is not mandatory and only has an effect for server components -import { cache } from 'react'; -import * as schema from './schema/pg'; -import { Pool } from 'pg'; +import { cache } from "react"; +import * as schema from "./schema/pg"; +import { Pool } from "pg"; export const getDb = cache(() => { - const pool = new Pool({ - // This env could be set either in the .env file or in wrangler.jsonc - connectionString: process.env.PG_URL, - // You don't want to reuse the same connection for multiple requests - maxUses: 1, - }) - return drizzle({client: pool, schema}) -}) + const pool = new Pool({ + // This env could be set either in the .env file or in wrangler.jsonc + connectionString: process.env.PG_URL, + // You don't want to reuse the same connection for multiple requests + maxUses: 1, + }); + return drizzle({ client: pool, schema }); +}); ``` #### D1 example + ```ts -import { getCloudflareContext } from '@opennextjs/cloudflare'; -import { drizzle } from 'drizzle-orm/d1'; -import { cache } from 'react'; -import * as schema from './schema/d1'; +import { getCloudflareContext } from "@opennextjs/cloudflare"; +import { drizzle } from "drizzle-orm/d1"; +import { cache } from "react"; +import * as schema from "./schema/d1"; export const getDb = cache(() => { - const {env} = getCloudflareContext() - return drizzle(env.MY_D1, {schema}) -}) + const { env } = getCloudflareContext(); + return drizzle(env.MY_D1, { schema }); +}); // This is the one to use for static routes (i.e. ISR/SSG) export const getDbAsync = cache(async () => { - const {env} = await getCloudflareContext({async: true}) - return drizzle(env.MY_D1, {schema}) -}) + const { env } = await getCloudflareContext({ async: true }); + return drizzle(env.MY_D1, { schema }); +}); ``` #### Hyperdrive example + ```ts -import { getCloudflareContext } from '@opennextjs/cloudflare'; -import { drizzle } from 'drizzle-orm/node-postgres'; -import { cache } from 'react'; -import * as schema from './schema/pg'; -import { Pool } from 'pg'; +import { getCloudflareContext } from "@opennextjs/cloudflare"; +import { drizzle } from "drizzle-orm/node-postgres"; +import { cache } from "react"; +import * as schema from "./schema/pg"; +import { Pool } from "pg"; export const getDb = cache(() => { - const {env} = getCloudflareContext() - const connectionString = env.HYPERDRIVE.connectionString - const pool = new Pool({ - // This env could be set either in the .env file or in wrangler.jsonc - connectionString: process.env.PG_URL, - // You don't want to reuse the same connection for multiple requests - maxUses: 1, - }) - return drizzle({client: pool, schema}) -}) + const { env } = getCloudflareContext(); + const connectionString = env.HYPERDRIVE.connectionString; + const pool = new Pool({ + // This env could be set either in the .env file or in wrangler.jsonc + connectionString: process.env.PG_URL, + // You don't want to reuse the same connection for multiple requests + maxUses: 1, + }); + return drizzle({ client: pool, schema }); +}); // This is the one to use for static routes (i.e. ISR/SSG) export const getDbAsync = cache(async () => { - const {env} = await getCloudflareContext({async: true}) - const connectionString = env.HYPERDRIVE.connectionString - const pool = new Pool({ - // This env could be set either in the .env file or in wrangler.jsonc - connectionString: process.env.PG_URL, - // You don't want to reuse the same connection for multiple requests - maxUses: 1, - }) - return drizzle({client: pool, schema}) -}) + const { env } = await getCloudflareContext({ async: true }); + const connectionString = env.HYPERDRIVE.connectionString; + const pool = new Pool({ + // This env could be set either in the .env file or in wrangler.jsonc + connectionString: process.env.PG_URL, + // You don't want to reuse the same connection for multiple requests + maxUses: 1, + }); + return drizzle({ client: pool, schema }); +}); ``` You can then use the `getDb` function to get a new client for each request. This will ensure that you don't run into any issues with connection pooling. ## Prisma + Prisma is a popular ORM for Node.js and TypeScript. It is designed to be easy to use and provides a lot of features out of the box. However, there are some subtleties to be aware of when using Prisma in Cloudflare Workers. ### `schema.prisma` -When using prisma in OpenNext, you do not want to provide an output directory for the generated client. + +When using prisma in OpenNext, you do not want to provide an output directory for the generated client. + ```prisma generator client { provider = "prisma-client-js" previewFeatures = ["driverAdapters"] } ``` + This is because the generated client needs to be patched by OpenNext to work with Cloudflare Workers. If you provide an output directory, OpenNext will not be able to patch the client and it will not work. ### `next.config.ts` + Because prisma has some specific exports for cloudflare workers, you need to add the following to your `next.config.ts` file: + ```ts const nextConfig: NextConfig = { - serverExternalPackages: [ - "@prisma/client", - ".prisma/client", - ] + serverExternalPackages: ["@prisma/client", ".prisma/client"], }; ``` + By doing this, this will ensure that both the generated client and the prisma client are included in the build for the correct runtime. ### `lib/db.ts` + Instead of creating a global client, you should create a new client for each request. This is because some adapters (like Postgres) will use a connection pool, and reuse the same connection for multiple requests. This is not allowed in Cloudflare Workers, and will cause subsequent requests to fail. #### D1 example -Instead of that : +Instead of that : + ```ts //lib/db.ts import { getCloudflareContext } from "@opennextjs/cloudflare"; -import { PrismaClient } from '@prisma/client'; -import { PrismaD1 } from '@prisma/adapter-d1' +import { PrismaClient } from "@prisma/client"; +import { PrismaD1 } from "@prisma/adapter-d1"; const { env } = getCloudflareContext(); -const adapter = new PrismaD1(env.MY_D1) -export const db = new PrismaClient() +const adapter = new PrismaD1(env.MY_D1); +export const db = new PrismaClient(); ``` + You should do this instead: ```ts @@ -151,66 +162,70 @@ import { getCloudflareContext } from "@opennextjs/cloudflare"; // You can use cache from react to cache the client during the same request // this is not mandatory and only has an effect for server components import { cache } from "react"; -import { PrismaClient } from '@prisma/client'; -import { PrismaD1 } from '@prisma/adapter-d1' +import { PrismaClient } from "@prisma/client"; +import { PrismaD1 } from "@prisma/adapter-d1"; export const getDb = cache(() => { - const { env } = getCloudflareContext(); - const adapter = new PrismaD1(env.MY_D1) - return new PrismaClient({ adapter }) -}) + const { env } = getCloudflareContext(); + const adapter = new PrismaD1(env.MY_D1); + return new PrismaClient({ adapter }); +}); // If you need access to `getCloudflareContext` in a static route (i.e. ISR/SSG), you should use the async version of `getCloudflareContext` to get the context. export const getDbAsync = async () => { - const { env } = await getCloudflareContext({async : true}); - const adapter = new PrismaD1(env.MY_D1) - const prisma = new PrismaClient({ adapter }) - return prisma -} + const { env } = await getCloudflareContext({ async: true }); + const adapter = new PrismaD1(env.MY_D1); + const prisma = new PrismaClient({ adapter }); + return prisma; +}; ``` + You can then use the `getDb` function to get a new client for each request. This will ensure that you don't run into any issues with connection pooling. #### PostgreSQL + You can also use Prisma with PostgreSQL. The setup is similar to the D1 setup above, but you need to use the `PrismaPostgres` adapter instead of the `PrismaD1` adapter. ```ts import { cache } from "react"; -import { PrismaClient } from '@prisma/client'; -import { PrismaPg } from '@prisma/adapter-pg' +import { PrismaClient } from "@prisma/client"; +import { PrismaPg } from "@prisma/adapter-pg"; export const getDb = cache(() => { - const connectionString = process.env.PG_URL ?? "" - const adapter = new PrismaPg({connectionString, maxUses: 1}) - const prisma = new PrismaClient({ adapter }) - return prisma -}) + const connectionString = process.env.PG_URL ?? ""; + const adapter = new PrismaPg({ connectionString, maxUses: 1 }); + const prisma = new PrismaClient({ adapter }); + return prisma; +}); ``` + You can then use the `getDb` function to get a new client for each request. This will ensure that you don't run into any issues with connection pooling. #### Hyperdrive + You can also use Prisma with Hyperdrive. The setup is similar to the PostgreSQL setup above. + ```ts //lib/db.ts import { getCloudflareContext } from "@opennextjs/cloudflare"; // You can use cache from react to cache the client during the same request // this is not mandatory and only has an effect for server components import { cache } from "react"; -import { PrismaClient } from '@prisma/client'; -import { PrismaPg } from '@prisma/adapter-pg' - +import { PrismaClient } from "@prisma/client"; +import { PrismaPg } from "@prisma/adapter-pg"; export const getDb = cache(() => { - const { env } = getCloudflareContext(); - const connectionString = env.HYPERDRIVE.connectionString; - const adapter = new PrismaPg({connectionString, maxUses: 1}) - return new PrismaClient({ adapter }) -}) + const { env } = getCloudflareContext(); + const connectionString = env.HYPERDRIVE.connectionString; + const adapter = new PrismaPg({ connectionString, maxUses: 1 }); + return new PrismaClient({ adapter }); +}); // This is the one to use for static routes (i.e. ISR/SSG) export const getDbAsync = async () => { - const { env } = await getCloudflareContext({async : true}); - const connectionString = env.HYPERDRIVE.connectionString; - const adapter = new PrismaPg({connectionString, maxUses: 1}) - return new PrismaClient({ adapter }) -} -``` \ No newline at end of file + const { env } = await getCloudflareContext({ async: true }); + const connectionString = env.HYPERDRIVE.connectionString; + const adapter = new PrismaPg({ connectionString, maxUses: 1 }); + return new PrismaClient({ adapter }); +}; +``` From 6d5a7ed262c7f2ff51017215bcc2bc3270a4ef7a Mon Sep 17 00:00:00 2001 From: conico974 Date: Fri, 2 May 2025 15:14:06 +0200 Subject: [PATCH 3/4] review fix --- pages/cloudflare/howtos/_meta.json | 2 +- pages/cloudflare/howtos/db.mdx | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pages/cloudflare/howtos/_meta.json b/pages/cloudflare/howtos/_meta.json index 1a2aa5d..31105ab 100644 --- a/pages/cloudflare/howtos/_meta.json +++ b/pages/cloudflare/howtos/_meta.json @@ -1,7 +1,7 @@ { "NextAuth": "NextAuth", "stripeAPI": "Stripe API", - "db": "Database", + "db": "Database & ORM", "dev-deploy": "Develop and Deploy", "env-vars": "Environment Variables", "image": "Image Optimization", diff --git a/pages/cloudflare/howtos/db.mdx b/pages/cloudflare/howtos/db.mdx index 24c4f2d..5ecd9fb 100644 --- a/pages/cloudflare/howtos/db.mdx +++ b/pages/cloudflare/howtos/db.mdx @@ -4,7 +4,7 @@ If you encounter issue with a specific library, please open an issue on the [Ope ## Drizzle -Drizzle is a TypeScript ORM for SQL databases. It is designed to be lightweight and easy to use, making it a great choice for Cloudflare Workers. +[Drizzle](https://developers.cloudflare.com/d1/reference/community-projects/#drizzle-orm) is a TypeScript ORM for SQL databases. It is designed to be lightweight and easy to use, making it a great choice for Cloudflare Workers. There is not much specific to configure in drizzle, but there is one important thing to note is that you don't want to have a global client. ### `lib/db.ts` @@ -24,6 +24,7 @@ import { Pool } from "pg"; const pool = new Pool({ connectionString: process.env.PG_URL, }); + export const db = drizzle({ client: pool, schema }); ``` @@ -108,7 +109,7 @@ You can then use the `getDb` function to get a new client for each request. This ## Prisma -Prisma is a popular ORM for Node.js and TypeScript. It is designed to be easy to use and provides a lot of features out of the box. However, there are some subtleties to be aware of when using Prisma in Cloudflare Workers. +[Prisma](https://developers.cloudflare.com/d1/reference/community-projects/#prisma-orm) is a popular ORM for Node.js and TypeScript. It is designed to be easy to use and provides a lot of features out of the box. However, there are some subtleties to be aware of when using Prisma in Cloudflare Workers. ### `schema.prisma` From 33fe5e204070158170bd6b2a4ba1a00bb1500bb7 Mon Sep 17 00:00:00 2001 From: conico974 Date: Fri, 2 May 2025 15:57:47 +0200 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Victor Berchet --- pages/cloudflare/howtos/db.mdx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/pages/cloudflare/howtos/db.mdx b/pages/cloudflare/howtos/db.mdx index 5ecd9fb..2b9d0cd 100644 --- a/pages/cloudflare/howtos/db.mdx +++ b/pages/cloudflare/howtos/db.mdx @@ -2,10 +2,10 @@ This page will show you how to setup some popular database ORM libraries to use If you encounter issue with a specific library, please open an issue on the [OpenNext GitHub repository](https://github.com/opennextjs/opennextjs-cloudflare/issues). -## Drizzle +## Drizzle ORM [Drizzle](https://developers.cloudflare.com/d1/reference/community-projects/#drizzle-orm) is a TypeScript ORM for SQL databases. It is designed to be lightweight and easy to use, making it a great choice for Cloudflare Workers. -There is not much specific to configure in drizzle, but there is one important thing to note is that you don't want to have a global client. +There is not much specific to configure in Drizzle, but there is one important thing to note is that you don't want to have a global client. ### `lib/db.ts` @@ -41,7 +41,6 @@ import { Pool } from "pg"; export const getDb = cache(() => { const pool = new Pool({ - // This env could be set either in the .env file or in wrangler.jsonc connectionString: process.env.PG_URL, // You don't want to reuse the same connection for multiple requests maxUses: 1, @@ -83,7 +82,6 @@ export const getDb = cache(() => { const { env } = getCloudflareContext(); const connectionString = env.HYPERDRIVE.connectionString; const pool = new Pool({ - // This env could be set either in the .env file or in wrangler.jsonc connectionString: process.env.PG_URL, // You don't want to reuse the same connection for multiple requests maxUses: 1, @@ -96,7 +94,6 @@ export const getDbAsync = cache(async () => { const { env } = await getCloudflareContext({ async: true }); const connectionString = env.HYPERDRIVE.connectionString; const pool = new Pool({ - // This env could be set either in the .env file or in wrangler.jsonc connectionString: process.env.PG_URL, // You don't want to reuse the same connection for multiple requests maxUses: 1, @@ -107,7 +104,7 @@ export const getDbAsync = cache(async () => { You can then use the `getDb` function to get a new client for each request. This will ensure that you don't run into any issues with connection pooling. -## Prisma +## Prisma ORM [Prisma](https://developers.cloudflare.com/d1/reference/community-projects/#prisma-orm) is a popular ORM for Node.js and TypeScript. It is designed to be easy to use and provides a lot of features out of the box. However, there are some subtleties to be aware of when using Prisma in Cloudflare Workers. @@ -134,7 +131,7 @@ const nextConfig: NextConfig = { }; ``` -By doing this, this will ensure that both the generated client and the prisma client are included in the build for the correct runtime. +By doing this, this will ensure that both the generated client and the prisma client are included in the build for the `workerd` runtime. ### `lib/db.ts`