11---
2- updated : 2024-08-23
2+ updated : 2025-07-01
33difficulty : Beginner
44pcx_content_type : tutorial
55title : Connect to a PostgreSQL database with Cloudflare Workers
@@ -63,11 +63,15 @@ cd postgres-tutorial
6363
6464## 2. Add the PostgreSQL connection library
6565
66- To connect to a PostgreSQL database, you will need the ` postgres ` library. In your Worker application directory, run the following command to install the library:
66+ To connect to a PostgreSQL database, you will need the ` pg ` library. In your Worker application directory, run the following command to install the library:
6767
68- <PackageManagers pkg = " postgres " />
68+ <PackageManagers pkg = " pg " />
6969
70- Make sure you are using ` postgres ` (` Postgres.js ` ) version ` 3.4.4 ` or higher. ` Postgres.js ` is compatible with both Pages and Workers.
70+ Next, install the TypeScript types for the ` pg ` library to enable type checking and autocompletion in your TypeScript code:
71+
72+ <PackageManagers pkg = " @types/pg" dev />
73+
74+ Make sure you are using ` pg ` (` node-postgres ` ) version ` 8.16.3 ` or higher.
7175
7276## 3. Configure the connection to the PostgreSQL database
7377
@@ -116,7 +120,7 @@ Configure each database parameter as an [environment variable](/workers/configur
116120DB_USERNAME = " postgres"
117121# Set your password by creating a secret so it is not stored as plain text
118122DB_HOST = " ep-aged-sound-175961.us-east-2.aws.neon.tech"
119- DB_PORT = " 5432"
123+ DB_PORT = 5432
120124DB_NAME = " productsdb"
121125```
122126
@@ -139,27 +143,34 @@ npx wrangler secret put DB_PASSWORD
139143Open your Worker's main file (for example, ` worker.ts ` ) and import the ` Client ` class from the ` pg ` library:
140144
141145``` typescript
142- import postgres from " postgres " ;
146+ import { Client } from " pg " ;
143147```
144148
145149In the ` fetch ` event handler, connect to the PostgreSQL database using your chosen method, either the connection string or the explicit parameters.
146150
147151### Use a connection string
148152
149153``` typescript
150- const sql = postgres (env .DB_URL );
154+ // create a new Client instance using the connection string
155+ const sql = new Client ({ connectionString: env .DB_URL });
156+ // connect to the PostgreSQL database
157+ await sql .connect ();
151158```
152159
153160### Set explicit parameters
154161
155162``` typescript
156- const sql = postgres ({
163+ // create a new Client instance using explicit parameters
164+ const sql = new Client ({
157165 username: env .DB_USERNAME ,
158166 password: env .DB_PASSWORD ,
159167 host: env .DB_HOST ,
160168 port: env .DB_PORT ,
161169 database: env .DB_NAME ,
170+ ssl: true , // Enable SSL for secure connections
162171});
172+ // connect to the PostgreSQL database
173+ await sql .connect ();
163174```
164175
165176## 5. Interact with the products database
@@ -184,30 +195,33 @@ CREATE TABLE products (
184195Replace the existing code in your ` worker.ts ` file with the following code:
185196
186197``` typescript
187- import postgres from " postgres " ;
198+ import { Client } from " pg " ;
188199
189200export default {
190201 async fetch(request , env , ctx ): Promise <Response > {
191- const sql = postgres (env .DB_URL , {
192- // Workers limit the number of concurrent external connections, so be sure to limit
193- // the size of the local connection pool that postgres.js may establish.
194- max: 5 ,
195-
196- // If you are using array types in your Postgres schema, it is necessary to fetch
197- // type information to correctly de/serialize them. However, if you are not using
198- // those, disabling this will save you an extra round-trip every time you connect.
199- fetch_types: false ,
200- });
201-
202- // Query the products table
203- const result = await sql ` SELECT * FROM products; ` ;
204-
205- // Return the result as JSON
206- const resp = new Response (JSON .stringify (result ), {
207- headers: { " Content-Type" : " application/json" },
202+ // Create a new Client instance using the connection string
203+ // or explicit parameters as shown in the previous steps.
204+ // Here, we are using the connection string method.
205+ const sql = new Client ({
206+ connectionString: env .DB_URL ,
208207 });
209-
210- return resp ;
208+ try {
209+ // Connect to the PostgreSQL database
210+ await sql .connect ();
211+
212+ // Query the products table
213+ const result = await sql .query (" SELECT * FROM products" );
214+
215+ // Return the result as JSON
216+ return new Response (JSON .stringify (result .rows ), {
217+ headers: {
218+ " Content-Type" : " application/json" ,
219+ },
220+ });
221+ } finally {
222+ // Clean up the client connection
223+ await sql .end ();
224+ }
211225 },
212226} satisfies ExportedHandler <Env >;
213227```
@@ -234,47 +248,60 @@ Assume the `products` table has the following columns: `id`, `name`, `descriptio
234248
235249Add the following code snippet inside the ` fetch ` event handler in your ` worker.ts ` file, before the existing query code:
236250
237- ``` typescript {9-32 }
238- import postgres from " postgres " ;
251+ ``` typescript {15-39 }
252+ import { Client } from " pg " ;
239253
240254export default {
241255 async fetch(request , env , ctx ): Promise <Response > {
242- const sql = postgres (env .DB_URL );
243-
244- const url = new URL (request .url );
245- if (request .method === " POST" && url .pathname === " /products" ) {
246- // Parse the request's JSON payload
247- const productData = await request .json ();
248-
249- // Insert the new product into the database
250- const values = {
251- name: productData .name ,
252- description: productData .description ,
253- price: productData .price ,
254- };
255- const insertResult = await sql `
256- INSERT INTO products ${sql (values )}
257- RETURNING *
258- ` ;
259-
260- // Return the inserted row as JSON
261- const insertResp = new Response (JSON .stringify (insertResult ), {
262- headers: { " Content-Type" : " application/json" },
256+ // Create a new Client instance using the connection string
257+ // or explicit parameters as shown in the previous steps.
258+ // Here, we are using the connection string method.
259+ const sql = new Client ({
260+ connectionString: env .DB_URL ,
261+ });
262+ try {
263+ // Connect to the PostgreSQL database
264+ await sql .connect ();
265+
266+ const url = new URL (request .url );
267+ if (request .method === " POST" && url .pathname === " /products" ) {
268+ // Parse the request's JSON payload
269+ const productData = (await request .json ()) as {
270+ name: string ;
271+ description: string ;
272+ price: number ;
273+ };
274+
275+ const name = productData .name ,
276+ description = productData .description ,
277+ price = productData .price ;
278+
279+ // Insert the new product into the products table
280+ const insertResult = await sql .query (
281+ ` INSERT INTO products(name, description, price) VALUES($1, $2, $3)
282+ RETURNING * ` ,
283+ [name , description , price ],
284+ );
285+
286+ // Return the inserted row as JSON
287+ return new Response (JSON .stringify (insertResult .rows ), {
288+ headers: { " Content-Type" : " application/json" },
289+ });
290+ }
291+
292+ // Query the products table
293+ const result = await sql .query (" SELECT * FROM products" );
294+
295+ // Return the result as JSON
296+ return new Response (JSON .stringify (result .rows ), {
297+ headers: {
298+ " Content-Type" : " application/json" ,
299+ },
263300 });
264-
265- // Clean up the client
266- return insertResp ;
301+ } finally {
302+ // Clean up the client connection
303+ await sql . end () ;
267304 }
268-
269- // Query the products table
270- const result = await sql ` SELECT * FROM products; ` ;
271-
272- // Return the result as JSON
273- const resp = new Response (JSON .stringify (result ), {
274- headers: { " Content-Type" : " application/json" },
275- });
276-
277- return resp ;
278305 },
279306} satisfies ExportedHandler <Env >;
280307```
@@ -344,7 +371,7 @@ Replace your existing connection string in your Worker code with the Hyperdrive
344371``` js {3-3}
345372export default {
346373 async fetch (request, env, ctx): Promise < Response> {
347- const sql = postgres ( env .HYPERDRIVE .connectionString )
374+ const sql = new Client ({connectionString : env .HYPERDRIVE .connectionString } )
348375
349376 const url = new URL (request .url );
350377
0 commit comments