node-postgres/docs/pages/guides/async-express.md
Rijk van Zanten 20d2c08027
Make async/await the primary examples in the docs (#2932)
* Correctly capitalize GitHub

* Add note on callbacks to index

* Add note on error handling

* Update client examples to use promises

* Update pooling examples

* Fix readme link

* Update cursor docs

* Update connecting examples

* Update Queries

* Update examples in pooling

* Update trx examples

* Update SSL example

* Update example

* Use ESM instead of CJS

* Update docs/pages/apis/cursor.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/apis/cursor.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/apis/pool.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/apis/pool.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/apis/pool.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/features/connecting.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/features/connecting.mdx

Co-authored-by: Charmander <~@charmander.me>

* Update docs/pages/features/ssl.mdx

Co-authored-by: Charmander <~@charmander.me>

---------

Co-authored-by: Charmander <~@charmander.me>
2023-05-31 11:25:24 -05:00

2.3 KiB

title
Express with async/await

My preferred way to use node-postgres (and all async code in node.js) is with async/await. I find it makes reasoning about control-flow easier and allows me to write more concise and maintainable code.

This is how I typically structure express web-applications with node-postgres to use async/await:

- app.js
- index.js
- routes/
  - index.js
  - photos.js
  - user.js
- db/
  - index.js <--- this is where I put data access code

That's the same structure I used in the project structure example.

My db/index.js file usually starts out like this:

import { Pool } from 'pg'

const pool = new Pool()

export const query = (text, params) => pool.query(text, params);

Then I will install express-promise-router and use it to define my routes. Here is my routes/user.js file:

import Router from 'express-promise-router'
import db from '../db.js'

// create a new express-promise-router
// this has the same API as the normal express router except
// it allows you to use async functions as route handlers
const router = new Router()

// export our router to be mounted by the parent application
export default router

router.get('/:id', async (req, res) => {
  const { id } = req.params
  const { rows } = await db.query('SELECT * FROM users WHERE id = $1', [id])
  res.send(rows[0])
})

Then in my routes/index.js file I'll have something like this which mounts each individual router into the main application:

// ./routes/index.js
import users from './user.js'
import photos from './photos.js'

const mountRoutes = (app) => {
  app.use('/users', users)
  app.use('/photos', photos)
  // etc..
}

export default mountRoutes

And finally in my app.js file where I bootstrap express I will have my routes/index.js file mount all my routes. The routes know they're using async functions but because of express-promise-router the main express app doesn't know and doesn't care!

// ./app.js
import express from 'express'
import mountRoutes from './routes.js'

const app = express()
mountRoutes(app)

// ... more express setup stuff can follow

Now you've got async/await, node-postgres, and express all working together!