@fastify/postgres

中文文档
6.1.2发布于 2026/11/04MITTypeScriptCommonJS构建来源已验证近 30 天下载 20.5万

Fastify PostgreSQL connection plugin

原始使用文档
文档目录14 节
  1. Install
  2. Compatibility
  3. Usage
  4. Name option
  5. Native option
  6. pg option
  7. SSL/TLS Usage
  8. Transact route option
  9. TypeScript Usage
  10. Development and Testing
  11. Docker approach
  12. Custom Postgres approach
  13. Acknowledgments
  14. License

@fastify/postgres

CI NPM version neostandard javascript style

Fastify PostgreSQL connection plugin; with this, you can share the same PostgreSQL connection pool in every part of your server. Under the hood node-postgres is used, and the options that you pass to register will be passed to the PostgreSQL pool builder.

Install

npm i pg @fastify/postgres

Compatibility

Plugin versionFastify version
>=6.x^5.x
^5.x^4.x
>=3.x <5.x^3.x
>=1.x <3.x^2.x
>=1.x <3.x^1.x

Please note that if a Fastify version is out of support, then so are the corresponding versions of this plugin in the table above. See Fastify's LTS policy for more details.

Usage

Add it to your project with register and you are done! This plugin will add the pg namespace to your Fastify instance, with the following properties:

connect: the function to get a connection from the pool
pool: the pool instance
Client: a client constructor for a single query
query: a utility to perform a query _without_ a transaction
transact: a utility to perform multiple queries _with_ a transaction

Example:

const fastify = require('fastify')()

fastify.register(require('@fastify/postgres'), {
  connectionString: 'postgres://postgres@localhost/postgres'
})

fastify.get('/user/:id', (req, reply) => {
  fastify.pg.connect(onConnect)

  function onConnect (err, client, release) {
    if (err) return reply.send(err)

    client.query(
      'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
      function onResult (err, result) {
        release()
        reply.send(err || result)
      }
    )
  }
})

fastify.listen({ port: 3000 }, err => {
  if (err) throw err
  console.log(`server listening on ${fastify.server.address().port}`)
})

Async await is supported as well!

const fastify = require('fastify')()

fastify.register(require('@fastify/postgres'), {
  connectionString: 'postgres://postgres@localhost/postgres'
})

fastify.get('/user/:id', async (req, reply) => {
  const client = await fastify.pg.connect()
  try {
    const { rows } = await client.query(
      'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
    )
    // Note: avoid doing expensive computation here, this will block releasing the client
    return rows
  } finally {
    // Release the client immediately after query resolves, or upon error
    client.release()
  }
})

fastify.listen({ port: 3000 }, err => {
  if (err) throw err
  console.log(`server listening on ${fastify.server.address().port}`)
})

Use of pg.query

const fastify = require('fastify')()

fastify.register(require('@fastify/postgres'), {
  connectionString: 'postgres://postgres@localhost/postgres'
})

fastify.get('/user/:id', (req, reply) => {
  fastify.pg.query(
    'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
    function onResult (err, result) {
      reply.send(err || result)
    }
  )
})

fastify.listen({ port: 3000 }, err => {
  if (err) throw err
  console.log(`server listening on ${fastify.server.address().port}`)
})

Use of pg.transact

const fastify = require('fastify')()

fastify.register(require('@fastify/postgres'), {
  connectionString: 'postgres://postgres@localhost/postgres'
})

fastify.post('/user/:username', (req, reply) => {
  // will return a promise, fastify will send the result automatically
  return fastify.pg.transact(async client => {
    // will resolve to an id, or reject with an error
    const id = await client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [req.params.username])

    // potentially do something with id

    return id
  })
})

/* or with a transaction callback

fastify.pg.transact(client => {
    return client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [req.params.username])
  },
  function onResult (err, result) {
    reply.send(err || result)
  }
})

*/

/* or with a commit callback

fastify.pg.transact((client, commit) => {
  client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [req.params.username], (err, id) => {
    commit(err, id)
  });
})

*/

fastify.listen({ port: 3000 }, err => {
  if (err) throw err
  console.log(`server listening on ${fastify.server.address().port}`)
})

As you can see there is no need to close the client since it is done internally. Promises and async await are supported as well.

Name option

If you need to have multiple databases set up, then you can name each one of them by passing name: 'foo'. It will then be accessible as fastify.pg.foo. You can use both unnamed and named postgres connections at once. There can be only one unnamed connection, and it will be accessible as fastify.pg.

const fastify = require('fastify')()

fastify.register(require('@fastify/postgres'), {
  connectionString: 'postgres://postgres@localhost/postgres',
  name: 'foo'
})

fastify.get('/user/:id', (req, reply) => {
  fastify.pg.foo.query(
    'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
    function onResult (err, result) {
      reply.send(err || result)
    }
  )
})

fastify.listen({ port: 3000 }, err => {
  if (err) throw err
  console.log(`server listening on ${fastify.server.address().port}`)
})

Native option

If you want maximum performance you can install pg-native, and pass native: true to the plugin options. Note: it requires PostgreSQL client libraries & tools installed, see instructions. Note: trying to use native options without successful installation of pg-native will return a warning and fallback to the regular pg module.

const fastify = require('fastify')()

fastify.register(require('@fastify/postgres'), {
  connectionString: 'postgres://postgres@localhost/postgres',
  native: true
})

fastify.get('/user/:id', (req, reply) => {
  fastify.pg.query(
    'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
    function onResult (err, result) {
      reply.send(err || result)
    }
  )
})

fastify.listen({ port: 3000 }, err => {
  if (err) throw err
  console.log(`server listening on ${fastify.server.address().port}`)
})

pg option

If you want to provide your own pg module, for example, to support packages like pg-range, you can provide an optional pg option with the patched library to use:

const fastify = require('fastify')()
const pg = require("pg");
require("pg-range").install(pg)

fastify.register(require('@fastify/postgres'), {
  connectionString: 'postgres://postgres@localhost/postgres',
  pg: pg
})

fastify.get('/user/:id', (req, reply) => {
  fastify.pg.query(
    'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
    function onResult (err, result) {
      reply.send(err || result)
    }
  )
})

fastify.listen({ port: 3000 }, err => {
  if (err) throw err
  console.log(`server listening on ${fastify.server.address().port}`)
})

SSL/TLS Usage

This plugin does not implement SSL itself: any option you pass to register (including ssl) is forwarded as-is to pg's Pool/Client constructor, so any SSL configuration supported by node-postgres works here too.

There are two ways to enable SSL:

1. Via the ssl option object

Useful when you need to disable certificate validation (e.g. connecting to a database with a self-signed certificate, such as on Heroku) or provide certs/keys directly.

const fastify = require('fastify')()

fastify.register(require('@fastify/postgres'), {
  connectionString: process.env.DATABASE_URL,
  ssl: {
    rejectUnauthorized: false
  }
})

2. Via SSL parameters in the connection string

You can also enable SSL by adding parameters such as sslmode, sslrootcert, sslcert and sslkey directly to the connection string:

const fastify = require('fastify')()

fastify.register(require('@fastify/postgres'), {
  connectionString: 'postgres://username:password@host:port/databasename?sslmode=verify-full&sslrootcert=yourrootcert&sslcert=yourclientcertificate&sslkey=yourclientkey'
})

⚠ Warning: Do not mix the two approaches. If the connection string contains any of sslmode, sslcert, sslkey or sslrootcert, those values take precedence over anything set in the ssl option object, and the ssl option will effectively be ignored. Pick one approach (either the ssl object, or SSL parameters in the connection string) and stick to it.

Transact route option

It is possible to automatically wrap a route handler in a transaction by using the transact option when registering a route with Fastify. Note that the option must be scoped within a pg options object to take effect.

query commands can then be accessed at request.pg or request.pg[name] and transact can be set for either the root pg client with value true or for a pg client at a particular namespace with value name. Note that the namespace needs to be set when registering the plugin in order to be available on the request object.

// transact set for the route pg client
fastify.get('/user/:id', { pg: { transact: true } }, (req, reply) => {
  // transaction wrapped queries, NO error handling
  req.pg.query('SELECT username FROM users WHERE id=1')
  req.pg.query('SELECT username FROM users WHERE id=2')
  req.pg.query('SELECT username FROM users WHERE id=3')
})

// transact set for a pg client at name
fastify.get('/user/:id', { pg: { transact: 'foo' } }, (req, reply) => {
  // transaction wrapped queries, NO error handling
  req.pg.foo.query('SELECT username FROM users WHERE id=1')
  req.pg.foo.query('SELECT username FROM users WHERE id=2')
  req.pg.foo.query('SELECT username FROM users WHERE id=3')
})

Important: rolling back a transaction relies on the handler failing and being caught by an onError hook. This means that the transaction wrapped route handler must not catch any errors internally.

In the plugin this works by using the preHandler hook to open the transaction, then the onError and onSend hooks to commit or rollback and release the client back to the pool.

TypeScript Usage

Install the compiler and typings for pg module:

npm i -D typescript @types/pg

More examples in the examples/typescript directory.

Development and Testing

Docker approach

First, start postgres with:

npm run postgres

Then you can, in another terminal, find the running docker, init the DB, then run the tests:

$ docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                    NAMES
28341f85c4cd        postgres:9.6-alpine   "docker-entrypoint.s…"   3 minutes ago       Up 3 minutes        0.0.0.0:5432->5432/tcp   jovial_shockley

$ docker exec -ti jovial_shockley /usr/local/bin/psql -d postgres -U postgres  -c 'CREATE TABLE users(id serial PRIMARY KEY, username VARCHAR (50) NOT NULL);'
CREATE TABLE

$ npm test

Custom Postgres approach

  1. Set up a database of your choice in a postgres server of your choice

  2. Create the required table using

    CREATE TABLE users(id serial PRIMARY KEY, username VARCHAR (50) NOT NULL);
    
  3. Specify a connection string to it in a DATABASE_TEST_URL environment variable when you run the tests

    DATABASE_TEST_URL="postgres://username:password@localhost/something_thats_a_test_database" npm test
    

Acknowledgments

This project is kindly sponsored by:

Past sponsors:

  • LetzDoIt

License

Licensed under MIT.

版本与发布记录

@fastify/postgres 共发布 15 个版本,首次发布于 2022/04/27;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
6.1.2latest2026/11/049 天前
6.1.12026/10/091 个月前
6.1.02026/07/084 个月前
6.0.22025/01/111.8 年前
6.0.12024/09/212 年前
6.0.0next2024/09/062 年前

关于 @fastify/postgres 的常见问题

@fastify/postgres 是什么?

Fastify PostgreSQL connection plugin

如何安装 @fastify/postgres?

在项目目录运行 npm install @fastify/postgres,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:pg(>=6.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@fastify/postgres 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@fastify/postgres 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@fastify/postgres 可以商用吗?

@fastify/postgres 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@fastify/postgres 的下载量有多少?

根据 npm 官方下载统计,@fastify/postgres 在 2026/10/15 – 2026/11/13 这 30 天内被下载 205,264 次,日均约 6,842 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@fastify/postgres 还在维护吗?

最新版本 6.1.2 发布于 2026/11/04(9 天前);至今共发布 15 个版本,其中过去 12 个月发布了 3 个;首次发布于 2022/04/27。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。