Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(examples): add postgres.js example (#42962)
- Loading branch information
1 parent
5e11f52
commit 10b635e
Showing
17 changed files
with
719 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DATABASE_URL=postgresql://user:pass@host/user/database?ssl=false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
.pnpm-debug.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# Postgres.js Example | ||
|
||
An example using [Postgres.js](https://github.com/porsager/postgres) in a Next.js project. | ||
|
||
## Deploy your own | ||
|
||
Once you have access to [the environment variables you'll need](#configure-environment-variables), deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example): | ||
|
||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-postgres&project-name=with-postgres&repository-name=with-postgres&env=DATABASE_URL&envDescription=Required%20to%20connect%20the%20app%20with%20Postgres) | ||
|
||
## How to use | ||
|
||
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: | ||
|
||
```bash | ||
npx create-next-app --example with-postgres with-postgres-app | ||
``` | ||
|
||
```bash | ||
yarn create next-app --example with-postgres with-postgres-app | ||
``` | ||
|
||
```bash | ||
pnpm create next-app --example with-postgres with-postgres-app | ||
``` | ||
|
||
## Configuration | ||
|
||
### Set up a Postgres database | ||
|
||
Set up a Postgres database locally or use your favorite provider. | ||
|
||
### Configure environment variables | ||
|
||
Copy the `.env.local.example` file in this directory to `.env.local` (this will be ignored by Git): | ||
|
||
```bash | ||
cp .env.local.example .env.local | ||
``` | ||
|
||
Set the `DATABASE_URL` variable in `.env.local` to the connection uri of your postgres database. | ||
|
||
### Apply migrations | ||
|
||
To setup up the migrations, use: | ||
|
||
```bash | ||
npm run migrate:up | ||
# or | ||
yarn migrate:up | ||
``` | ||
|
||
### Start Next.js in development mode | ||
|
||
```bash | ||
npm run dev | ||
# or | ||
yarn dev | ||
``` | ||
|
||
Your app should now be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions). | ||
|
||
## Deploy on Vercel | ||
|
||
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
const dotenv = require('dotenv') | ||
const { parse } = require('pg-connection-string') | ||
|
||
dotenv.config({ path: '.env.local' }) | ||
|
||
const options = parse(process.env.DATABASE_URL || '') | ||
|
||
module.exports = options |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import postgres from 'postgres' | ||
|
||
const sql = postgres(process.env.DATABASE_URL as string) | ||
|
||
export default sql |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import sql from './db' | ||
|
||
export interface ToDo { | ||
id: number | ||
text: string | ||
done: boolean | ||
} | ||
|
||
export async function list() { | ||
return await sql<ToDo[]>` | ||
SELECT id, text, done FROM todos | ||
ORDER BY id | ||
` | ||
} | ||
|
||
export async function create(todo: ToDo) { | ||
return await sql<ToDo[]>` | ||
INSERT INTO todos (text, done) VALUES (${todo.text}, false) | ||
RETURNING id, text, done | ||
` | ||
} | ||
|
||
export async function update(todo: ToDo) { | ||
return await sql<ToDo[]>` | ||
UPDATE todos SET done=${todo.done} WHERE id=${todo.id} | ||
RETURNING id, text, done | ||
` | ||
} | ||
|
||
export async function remove(todo: ToDo) { | ||
return await sql<ToDo[]>` | ||
DELETE FROM todos WHERE id=${todo.id} | ||
RETURNING id, text, done | ||
` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
exports.up = async function (sql) { | ||
await sql` | ||
CREATE TABLE IF NOT EXISTS todos ( | ||
id SERIAL PRIMARY KEY NOT NULL, | ||
text CHARACTER VARYING(255) NOT NULL, | ||
done BOOLEAN NOT NULL DEFAULT FALSE | ||
) | ||
` | ||
} | ||
|
||
exports.down = async function (sql) { | ||
await sql` | ||
DROP TABLE IF EXISTS todos | ||
` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = { | ||
reactStrictMode: true, | ||
swcMinify: true, | ||
} | ||
|
||
module.exports = nextConfig |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"dev": "next dev", | ||
"build": "next build", | ||
"start": "next start", | ||
"migrate:up": "ley up", | ||
"migrate:down": "ley down" | ||
}, | ||
"dependencies": { | ||
"@types/node": "^18.11.9", | ||
"@types/react": "^18.0.25", | ||
"@types/react-dom": "^18.0.9", | ||
"next": "latest", | ||
"postgres": "^3.3.1", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"typescript": "^4.8.4" | ||
}, | ||
"devDependencies": { | ||
"dotenv": "^16.0.3", | ||
"ley": "^0.8.1", | ||
"pg-connection-string": "^2.5.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import type { AppProps } from 'next/app' | ||
|
||
import '../styles/globals.css' | ||
|
||
export default function App({ Component, pageProps }: AppProps) { | ||
return <Component {...pageProps} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { NextApiRequest, NextApiResponse } from 'next' | ||
import { type ToDo } from '../../lib/todos' | ||
import * as todos from '../../lib/todos' | ||
|
||
export default async function handler( | ||
req: NextApiRequest, | ||
res: NextApiResponse<ToDo[] | string> | ||
) { | ||
switch (req.method) { | ||
case 'GET': | ||
return res.status(200).json(await todos.list()) | ||
case 'POST': | ||
return res.status(201).json(await todos.create(req.body)) | ||
case 'PUT': | ||
const updated = await todos.update(req.body) | ||
return res.status(updated.length > 0 ? 200 : 404).json(updated) | ||
case 'DELETE': | ||
const removed = await todos.remove(req.body) | ||
return res.status(removed.length > 0 ? 204 : 404).end() | ||
default: | ||
return res.status(405).send('Method Not Allowed') | ||
} | ||
} |
Oops, something went wrong.