|
| 1 | +--- |
| 2 | +title: PostgreSQL Database |
| 3 | +navigation.title: PostgreSQL |
| 4 | +description: Learn how to use PostgreSQL in your Nuxt application deployed on Cloudflare Workers / Pages and how to speed up your queries using Hyperdrive. |
| 5 | +--- |
| 6 | + |
| 7 | +## Pre-requisites |
| 8 | + |
| 9 | +Cloudflare does not host PostgreSQL databases, you need to setup your own PostgreSQL database. |
| 10 | + |
| 11 | +::note{to="https://www.postgresql.org/support/professional_hosting/" target="_blank" icon="i-logos-postgresql"} |
| 12 | +See a list of professional PostgreSQL hosting providers. |
| 13 | +:: |
| 14 | + |
| 15 | +If you prefer to use Cloudflare services, you can use Cloudflare D1 which is built on SQLite, see our [Database](/docs/features/database) section. |
| 16 | + |
| 17 | +## Setup |
| 18 | + |
| 19 | +1. Make sure to use the `@nuxthub/core` module, see the [installation section](/docs/getting-started/installation#add-to-a-nuxt-project) for instructions. |
| 20 | + |
| 21 | +```ts [nuxt.config.ts] |
| 22 | +export default defineNuxtConfig({ |
| 23 | + modules: ['@nuxthub/core',], |
| 24 | +}); |
| 25 | +``` |
| 26 | + |
| 27 | +::note |
| 28 | +The module ensures that you can connect to your PostgreSQL database using [Cloudflare TCP Sockets](https://developers.cloudflare.com/workers/runtime-apis/tcp-sockets/.) |
| 29 | +:: |
| 30 | + |
| 31 | +2. Install the [`postgres`](https://www.npmjs.com/package/postgres) NPM package in your project. |
| 32 | + |
| 33 | +```bash |
| 34 | +npx nypm add postgres |
| 35 | +``` |
| 36 | + |
| 37 | +::tip{icon="i-ph-rocket-launch"} |
| 38 | +That's it, you can now use the `postgres` package to connect to your PostgreSQL database. |
| 39 | +:: |
| 40 | + |
| 41 | +::warning |
| 42 | +Please note that [`pg`](https://www.npmjs.com/package/pg) is not compatible at the moment. |
| 43 | +:: |
| 44 | + |
| 45 | +## Usage |
| 46 | + |
| 47 | +We can add our PostgreSQL database connection in our `.env` file. |
| 48 | + |
| 49 | +```bash [.env] |
| 50 | +NUXT_POSTGRES_URL=postgresql://user:password@localhost:5432/database |
| 51 | +``` |
| 52 | + |
| 53 | +Then, we can create a `usePostgres()` server util to connect to our database in our API route. |
| 54 | + |
| 55 | +```ts [server/utils/postgres.ts] |
| 56 | +import postgres from 'postgres' |
| 57 | + |
| 58 | +export function usePostgres () { |
| 59 | + if (!process.env.NUXT_POSTGRES_URL) { |
| 60 | + throw createError('Missing `NUXT_POSTGRES_URL` environment variable') |
| 61 | + } |
| 62 | + |
| 63 | + return postgres(process.env.NUXT_POSTGRES_URL as string, { |
| 64 | + ssl: 'require' |
| 65 | + }) |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +We can now use the `usePostgres()` function to connect to our database in our API route. |
| 70 | + |
| 71 | +```ts [server/api/db.ts] |
| 72 | +export default eventHandler(async (event) => { |
| 73 | + const sql = usePostgres() |
| 74 | + |
| 75 | + const products = await sql`SELECT * FROM products` |
| 76 | + |
| 77 | + // Ensure the database connection is closed after the request is processed |
| 78 | + event.waitUntil(sql.end()) |
| 79 | + return products |
| 80 | +}) |
| 81 | +``` |
| 82 | + |
| 83 | +::tip |
| 84 | +You may notice that we don't import `usePostgres()`. This is because Nuxt auto-imports the exported variables & functions from `server/utils/*.ts` when used. |
| 85 | +:: |
| 86 | + |
| 87 | +## Hyperdrive |
| 88 | + |
| 89 | +[Hyperdrive](https://developers.cloudflare.com/hyperdrive/) is a Cloudflare service that accelerates queries you make to existing databases, making it faster to access your data from across the globe. By maintaining a connection pool to your database within Cloudflare’s network, Hyperdrive reduces seven round-trips to your database before you can even send a query: the TCP handshake (1x), TLS negotiation (3x), and database authentication (3x). |
| 90 | + |
| 91 | +::important{to="https://developers.cloudflare.com/hyperdrive/platform/pricing/" target="_blank"} |
| 92 | +Hyperdrive is only available on the Workers Paid plan ($5/month), **learn more**. |
| 93 | +:: |
| 94 | + |
| 95 | +To use Hyperdrive in your Nuxt application: |
| 96 | +1. [Create a Hyperdrive configuration](https://dash.cloudflare.com/?to=/:account/workers/hyperdrive/create) |
| 97 | +2. Add your Hyperdrive ID in your `nuxt.config.ts` file |
| 98 | + |
| 99 | +```ts [nuxt.config.ts] |
| 100 | +export default defineNuxtConfig({ |
| 101 | + modules: ['@nuxthub/core'], |
| 102 | + hub: { |
| 103 | + bindings: { |
| 104 | + hyperdrive: { |
| 105 | + // <BINDING_NAME>: <HYPERDRIVE_ID> |
| 106 | + POSTGRES: 'your-hyperdrive-id' |
| 107 | + } |
| 108 | + } |
| 109 | + } |
| 110 | +}) |
| 111 | +``` |
| 112 | + |
| 113 | +3. Update our `usePostgres()` function to use the `POSTGRES` binding when available. |
| 114 | + |
| 115 | +```ts [server/utils/postgres.ts] |
| 116 | +import type { Hyperdrive } from '@cloudflare/workers-types' |
| 117 | +import postgres from 'postgres' |
| 118 | + |
| 119 | +export function usePostgres() { |
| 120 | + const hyperdrive = process.env.POSTGRES as Hyperdrive | undefined |
| 121 | + const dbUrl = hyperdrive?.connectionString || process.env.NUXT_POSTGRES_URL |
| 122 | + if (!dbUrl) { |
| 123 | + throw createError('Missing `POSTGRES` hyperdrive binding or `NUXT_POSTGRES_URL` env variable') |
| 124 | + } |
| 125 | + |
| 126 | + return postgres(dbUrl, { |
| 127 | + ssl: !hyperdrive ? 'require' : undefined |
| 128 | + }) |
| 129 | +} |
| 130 | +``` |
| 131 | + |
| 132 | +::warning |
| 133 | +Hyperdrive is currently not available in development mode at the moment. We are working on a solution to make it work in development mode and remote storage with an upcoming `hubHyperdrive()`. |
| 134 | +:: |
| 135 | + |
| 136 | +4. [Deploy your application](/docs/getting-started/deploy) with the NuxtHub CLI or Admin to make sure the Hyperdrive bindings are set. |
| 137 | + |
| 138 | +::tip{icon="i-ph-rocket-launch"} |
| 139 | +You can now access your PostgreSQL database from anywhere in the world at maximum speed. |
| 140 | +:: |
0 commit comments