Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit 76adea6

Browse files
committed
docs: add postgres-db guide
1 parent 66417d4 commit 76adea6

File tree

7 files changed

+223
-0
lines changed

7 files changed

+223
-0
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
---
2+
description: 'How to work with Nitric SQL Databases using PostgreSQL'
3+
tags:
4+
- Databases
5+
languages:
6+
- typescript
7+
- javascript
8+
published_at: 2025-03-18
9+
---
10+
11+
# Nitric SQL Databases with PostgreSQL
12+
13+
This guide demonstrates how to use PostgreSQL with Nitric's [SQL database](/sql) feature. We will be creating a simple to-do app. The finished source can be found [here](https://github.com/nitrictech/examples/tree/main/v1/nitric-pgsql).
14+
15+
<Note>
16+
SQL databases are currently in preview and only support PostgreSQL deployed to
17+
AWS.
18+
</Note>
19+
20+
## Create a new Nitric project
21+
22+
The first step is to create a new Nitric TypeScript project using the [Nitric CLI](/reference/cli).
23+
24+
```bash
25+
nitric new todo-app ts-starter
26+
npm install
27+
```
28+
29+
## Enabling SQL databases
30+
31+
SQL databases are currently in Preview. To enable this feature in your project, add the following to your `nitric.yaml` file:
32+
33+
```yaml title: nitric.yaml
34+
preview:
35+
- sql-databases
36+
```
37+
38+
Ensure your CLI is at least `v1.42` and your AWS provider is at least `v1.6.2`.
39+
40+
## Install PostgreSQL client
41+
42+
```bash
43+
npm install pg
44+
```
45+
46+
## Create a Nitric SQL Database and Connect to it
47+
48+
Establish a connection to a PostgreSQL database using Nitric’s `sql` feature and the `pg` library.
49+
50+
```ts title: resources/db.ts
51+
import { sql } from '@nitric/sdk'
52+
import { Client } from 'pg'
53+
54+
const db = sql('todo-db', {
55+
migrations: 'file://migrations/todos',
56+
})
57+
58+
let client: Client
59+
60+
const getClient = async () => {
61+
if (!client) {
62+
const connectionString = await db.connectionString()
63+
client = new Client({ connectionString })
64+
await client.connect()
65+
}
66+
return client
67+
}
68+
69+
export default getClient
70+
```
71+
72+
## Database Migrations
73+
74+
Create a migration file to define the `todos` table.
75+
76+
```sql title: 'migrations/1_create_table.up.sql'
77+
CREATE TABLE IF NOT EXISTS todos (
78+
id SERIAL PRIMARY KEY,
79+
text TEXT NOT NULL,
80+
done BOOLEAN DEFAULT FALSE
81+
);
82+
```
83+
84+
## Developing the API
85+
86+
### Building the API
87+
88+
Delete the `services/hello.ts` file and create a new one called `todos.ts`, which will contain our API endpoints.
89+
90+
```ts title: services/todos.ts
91+
import { api } from '@nitric/sdk'
92+
import getClient from '../resources/db'
93+
94+
const mainApi = api('main')
95+
96+
// Fetch all todos
97+
mainApi.get('/todos', async (ctx) => {
98+
const client = await getClient()
99+
const result = await client.query('SELECT * FROM todos ORDER BY id ASC')
100+
return ctx.res.json(result.rows)
101+
})
102+
103+
// Insert a new todo
104+
mainApi.post('/todos/:id', async (ctx) => {
105+
const { id } = ctx.req.params
106+
const { text } = ctx.req.json()
107+
const client = await getClient()
108+
await client.query('INSERT INTO todos (id, text, done) VALUES ($1, $2, $3)', [
109+
parseInt(id),
110+
text,
111+
false,
112+
])
113+
})
114+
115+
// Update text of a todo
116+
mainApi.patch('/todos/:id', async (ctx) => {
117+
const { id } = ctx.req.params
118+
const { text } = ctx.req.json()
119+
const client = await getClient()
120+
await client.query('UPDATE todos SET text = $1 WHERE id = $2', [
121+
text,
122+
parseInt(id),
123+
])
124+
})
125+
126+
// Toggle todo completion status
127+
mainApi.patch('/todos/:id/toggle', async (ctx) => {
128+
const { id } = ctx.req.params
129+
const client = await getClient()
130+
const todo = await client.query('SELECT done FROM todos WHERE id = $1', [
131+
parseInt(id),
132+
])
133+
134+
if (todo.rows.length > 0) {
135+
const newDone = !todo.rows[0].done
136+
await client.query('UPDATE todos SET done = $1 WHERE id = $2', [
137+
newDone,
138+
parseInt(id),
139+
])
140+
}
141+
})
142+
143+
// Delete a todo
144+
mainApi.delete('/todos/:id', async (ctx) => {
145+
const { id } = ctx.req.params
146+
const client = await getClient()
147+
await client.query('DELETE FROM todos WHERE id = $1', [parseInt(id)])
148+
})
149+
```
150+
151+
### Start testing with `nitric start`
152+
153+
Run `nitric start` to start your local database and APIs.
154+
155+
```bash
156+
nitric start
157+
```
158+
159+
Using the dashboard, apply your migrations from the databases tab to initialize your local db.
160+
161+
![Apply migrations](/docs/images/guides/nitric-and-pgsql/migrations.png)
162+
163+
### Add some todos using the Nitric dashboard
164+
165+
Open the local dashboard at <a target="_blank" href="http://localhost:49152">localhost:49152</a>, then navigate to the `POST /todos/{id}` endpoint and fill in an `id` as the path param.
166+
167+
![Add id param for creating a todo](/docs/images/guides/nitric-and-pgsql/step-1.png)
168+
169+
Then add some content to the body of the request, stating the `text` key and value of the todo task and click send.
170+
171+
![Add text content for the todo](/docs/images/guides/nitric-and-pgsql/step-2.png)
172+
173+
Let's check our todo got created by calling the `GET /todos` endpoint, which will list all todos.
174+
175+
![Check that our todo get created](/docs/images/guides/nitric-and-pgsql/step-3.png)
176+
177+
Let's toggle our todo as done, navigate to the `PATCH /todos/{id}/toggle` and enter the correct `id` to toggle.
178+
179+
![Toggle our todo as done](/docs/images/guides/nitric-and-pgsql/step-4.png)
180+
181+
Finally, let's check our todo got toggled to done by calling the `GET /todos` endpoint.
182+
183+
![View the todo change](/docs/images/guides/nitric-and-pgsql/step-5.png)
184+
185+
Feel free to test the other endpoints to update or delete the todo items.
186+
187+
## Deploying to AWS
188+
189+
### Create your stack
190+
191+
Create an AWS stack called `aws-staging` for your staging environment.
192+
193+
```bash
194+
nitric stack new aws-staging aws
195+
```
196+
197+
Inside the stack file, ensure you set your `region`.
198+
199+
```yaml title:nitric.dev.yaml
200+
provider: nitric/aws@latest
201+
region: us-east-2
202+
```
203+
204+
### Deploy
205+
206+
Deploy to AWS using the `nitric up` command. Ensure you have set up your [AWS credentials](/providers/pulumi/aws#usage) correctly.
207+
208+
```bash
209+
nitric up
210+
```
211+
212+
### Tear down
213+
214+
To avoid unwanted costs of running your test app, you can tear down the stack using the `nitric down` command.
215+
216+
```bash
217+
nitric down
218+
```
219+
220+
### Prefer to use an ORM? We also have these guides:
221+
222+
- [Nitric SQL with Drizzle](./nitric-and-drizzle).
223+
- [Nitric SQL with Prisma](./nitric-and-prisma).
149 KB
Loading
92.8 KB
Loading
116 KB
Loading
122 KB
Loading
93.5 KB
Loading
126 KB
Loading

0 commit comments

Comments
 (0)