{"id":13836120,"url":"https://github.com/fastify/fastify-postgres","last_synced_at":"2025-05-15T07:03:15.461Z","repository":{"id":25797314,"uuid":"106552085","full_name":"fastify/fastify-postgres","owner":"fastify","description":"Fastify PostgreSQL connection plugin","archived":false,"fork":false,"pushed_at":"2025-05-01T04:06:07.000Z","size":222,"stargazers_count":198,"open_issues_count":3,"forks_count":34,"subscribers_count":17,"default_branch":"main","last_synced_at":"2025-05-01T05:19:06.811Z","etag":null,"topics":["fastify","fastify-plugin","postgres"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/@fastify/postgres","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fastify.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"fastify","open_collective":"fastify"}},"created_at":"2017-10-11T12:36:23.000Z","updated_at":"2025-05-01T04:06:03.000Z","dependencies_parsed_at":"2023-01-14T03:26:30.465Z","dependency_job_id":"472c6c71-64d5-4459-b326-2405b82f86ff","html_url":"https://github.com/fastify/fastify-postgres","commit_stats":{"total_commits":209,"total_committers":38,"mean_commits":5.5,"dds":0.7607655502392344,"last_synced_commit":"272b0d4330b37ea181379f243887907289c89e20"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-postgres","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-postgres/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-postgres/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fastify%2Ffastify-postgres/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fastify","download_url":"https://codeload.github.com/fastify/fastify-postgres/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254291961,"owners_count":22046424,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastify","fastify-plugin","postgres"],"created_at":"2024-08-04T15:00:35.967Z","updated_at":"2025-05-15T07:03:15.438Z","avatar_url":"https://github.com/fastify.png","language":"JavaScript","readme":"# @fastify/postgres\n\n[![CI](https://github.com/fastify/fastify-postgres/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/fastify/fastify-postgres/actions/workflows/ci.yml)\n[![NPM version](https://img.shields.io/npm/v/@fastify/postgres.svg?style=flat)](https://www.npmjs.com/package/@fastify/postgres)\n[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](https://github.com/neostandard/neostandard)\n\nFastify PostgreSQL connection plugin; with this, you can share the same PostgreSQL connection pool in every part of your server.\nUnder the hood [node-postgres](https://github.com/brianc/node-postgres) is used, and the options that you pass to `register` will be passed to the PostgreSQL pool builder.\n\n## Install\n```\nnpm i pg @fastify/postgres\n```\n\n### Compatibility\n| Plugin version | Fastify version |\n| ---------------|-----------------|\n| `\u003e=6.x`        | `^5.x`          |\n| `^5.x`         | `^4.x`          |\n| `\u003e=3.x \u003c5.x`   | `^3.x`          |\n| `\u003e=1.x \u003c3.x`   | `^2.x`          |\n| `\u003e=1.x \u003c3.x`   | `^1.x`          |\n\n\nPlease note that if a Fastify version is out of support, then so are the corresponding versions of this plugin\nin the table above.\nSee [Fastify's LTS policy](https://github.com/fastify/fastify/blob/main/docs/Reference/LTS.md) for more details.\n\n## Usage\nAdd it to your project with `register` and you are done!\nThis plugin will add the `pg` namespace to your Fastify instance, with the following properties:\n```\nconnect: the function to get a connection from the pool\npool: the pool instance\nClient: a client constructor for a single query\nquery: a utility to perform a query _without_ a transaction\ntransact: a utility to perform multiple queries _with_ a transaction\n```\n\nExample:\n```js\nconst fastify = require('fastify')()\n\nfastify.register(require('@fastify/postgres'), {\n  connectionString: 'postgres://postgres@localhost/postgres'\n})\n\nfastify.get('/user/:id', (req, reply) =\u003e {\n  fastify.pg.connect(onConnect)\n\n  function onConnect (err, client, release) {\n    if (err) return reply.send(err)\n\n    client.query(\n      'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],\n      function onResult (err, result) {\n        release()\n        reply.send(err || result)\n      }\n    )\n  }\n})\n\nfastify.listen({ port: 3000 }, err =\u003e {\n  if (err) throw err\n  console.log(`server listening on ${fastify.server.address().port}`)\n})\n```\n\nAsync await is supported as well!\n```js\nconst fastify = require('fastify')()\n\nfastify.register(require('@fastify/postgres'), {\n  connectionString: 'postgres://postgres@localhost/postgres'\n})\n\nfastify.get('/user/:id', async (req, reply) =\u003e {\n  const client = await fastify.pg.connect()\n  try {\n    const { rows } = await client.query(\n      'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],\n    )\n    // Note: avoid doing expensive computation here, this will block releasing the client\n    return rows\n  } finally {\n    // Release the client immediately after query resolves, or upon error\n    client.release()\n  }\n})\n\nfastify.listen({ port: 3000 }, err =\u003e {\n  if (err) throw err\n  console.log(`server listening on ${fastify.server.address().port}`)\n})\n```\nUse of `pg.query`\n```js\nconst fastify = require('fastify')()\n\nfastify.register(require('@fastify/postgres'), {\n  connectionString: 'postgres://postgres@localhost/postgres'\n})\n\nfastify.get('/user/:id', (req, reply) =\u003e {\n  fastify.pg.query(\n    'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],\n    function onResult (err, result) {\n      reply.send(err || result)\n    }\n  )\n})\n\nfastify.listen({ port: 3000 }, err =\u003e {\n  if (err) throw err\n  console.log(`server listening on ${fastify.server.address().port}`)\n})\n```\n\nUse of `pg.transact`\n```js\nconst fastify = require('fastify')()\n\nfastify.register(require('@fastify/postgres'), {\n  connectionString: 'postgres://postgres@localhost/postgres'\n})\n\nfastify.post('/user/:username', (req, reply) =\u003e {\n  // will return a promise, fastify will send the result automatically\n  return fastify.pg.transact(async client =\u003e {\n    // will resolve to an id, or reject with an error\n    const id = await client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [req.params.username])\n\n    // potentially do something with id\n\n    return id\n  })\n})\n\n/* or with a transaction callback\n\nfastify.pg.transact(client =\u003e {\n    return client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [req.params.username])\n  },\n  function onResult (err, result) {\n    reply.send(err || result)\n  }\n})\n\n*/\n\n/* or with a commit callback\n\nfastify.pg.transact((client, commit) =\u003e {\n  client.query('INSERT INTO users(username) VALUES($1) RETURNING id', [req.params.username], (err, id) =\u003e {\n    commit(err, id)\n  });\n})\n\n*/\n\nfastify.listen({ port: 3000 }, err =\u003e {\n  if (err) throw err\n  console.log(`server listening on ${fastify.server.address().port}`)\n})\n```\n\nAs you can see there is no need to close the client since it is done internally. Promises and async await are supported as well.\n\n### Name option\nIf 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`.\nYou 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`.\n\n```js\nconst fastify = require('fastify')()\n\nfastify.register(require('@fastify/postgres'), {\n  connectionString: 'postgres://postgres@localhost/postgres',\n  name: 'foo'\n})\n\nfastify.get('/user/:id', (req, reply) =\u003e {\n  fastify.pg.foo.query(\n    'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],\n    function onResult (err, result) {\n      reply.send(err || result)\n    }\n  )\n})\n\nfastify.listen({ port: 3000 }, err =\u003e {\n  if (err) throw err\n  console.log(`server listening on ${fastify.server.address().port}`)\n})\n```\n\n### Native option\nIf you want maximum performance you can install [pg-native](https://github.com/brianc/node-pg-native), and pass `native: true` to the plugin options.\n*Note: it requires PostgreSQL client libraries \u0026 tools installed, see [instructions](https://github.com/brianc/node-pg-native#install).*\nNote: trying to use native options without successful installation of `pg-native` will return a warning and fallback to the regular `pg` module.\n\n```js\nconst fastify = require('fastify')()\n\nfastify.register(require('@fastify/postgres'), {\n  connectionString: 'postgres://postgres@localhost/postgres',\n  native: true\n})\n\nfastify.get('/user/:id', (req, reply) =\u003e {\n  fastify.pg.query(\n    'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],\n    function onResult (err, result) {\n      reply.send(err || result)\n    }\n  )\n})\n\nfastify.listen({ port: 3000 }, err =\u003e {\n  if (err) throw err\n  console.log(`server listening on ${fastify.server.address().port}`)\n})\n```\n\n### `pg` option\nIf you want to provide your own `pg` module, for example, to support packages like [`pg-range`](https://www.npmjs.com/package/pg-range), you can provide an optional `pg` option with the patched library to use:\n\n```js\nconst fastify = require('fastify')()\nconst pg = require(\"pg\");\nrequire(\"pg-range\").install(pg)\n\nfastify.register(require('@fastify/postgres'), {\n  connectionString: 'postgres://postgres@localhost/postgres',\n  pg: pg\n})\n\nfastify.get('/user/:id', (req, reply) =\u003e {\n  fastify.pg.query(\n    'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],\n    function onResult (err, result) {\n      reply.send(err || result)\n    }\n  )\n})\n\nfastify.listen({ port: 3000 }, err =\u003e {\n  if (err) throw err\n  console.log(`server listening on ${fastify.server.address().port}`)\n})\n```\n\n### Transact route option\nIt 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.\n\n`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.\n\n```js\n// transact set for the route pg client\nfastify.get('/user/:id', { pg: { transact: true } }, (req, reply) =\u003e {\n  // transaction wrapped queries, NO error handling\n  req.pg.query('SELECT username FROM users WHERE id=1')\n  req.pg.query('SELECT username FROM users WHERE id=2')\n  req.pg.query('SELECT username FROM users WHERE id=3')\n})\n\n// transact set for a pg client at name\nfastify.get('/user/:id', { pg: { transact: 'foo' } }, (req, reply) =\u003e {\n  // transaction wrapped queries, NO error handling\n  req.pg.foo.query('SELECT username FROM users WHERE id=1')\n  req.pg.foo.query('SELECT username FROM users WHERE id=2')\n  req.pg.foo.query('SELECT username FROM users WHERE id=3')\n})\n```\n\nImportant: 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.\n\nIn 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.\n\n## TypeScript Usage\n\nInstall the compiler and typings for pg module:\n\n```shell script\nnpm i -D typescript @types/pg\n```\n\nMore examples in the [examples/typescript](./examples/typescript) directory.\n\n## Development and Testing\n\n### Docker approach\n\nFirst, start postgres with:\n\n```\n$ npm run postgres\n```\n\nThen you can, in another terminal, find the running docker, init the DB, then run the tests:\n\n```\n$ docker ps\nCONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                    NAMES\n28341f85c4cd        postgres:9.6-alpine   \"docker-entrypoint.s…\"   3 minutes ago       Up 3 minutes        0.0.0.0:5432-\u003e5432/tcp   jovial_shockley\n\n$ 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);'\nCREATE TABLE\n\n$ npm test\n```\n\n### Custom Postgres approach\n\n1. Set up a database of your choice in a postgres server of your choice\n2. Create the required table using\n    ```sql\n    CREATE TABLE users(id serial PRIMARY KEY, username VARCHAR (50) NOT NULL);\n    ```\n3. Specify a connection string to it in a `DATABASE_TEST_URL` environment variable when you run the tests\n    ```bash\n    DATABASE_TEST_URL=\"postgres://username:password@localhost/something_thats_a_test_database\" npm test\n    ```\n\n## Acknowledgments\n\nThis project is kindly sponsored by:\n- [nearForm](https://www.nearform.com)\n- [LetzDoIt](https://www.letzdoitapp.com/)\n\n## License\n\nLicensed under [MIT](./LICENSE).\n","funding_links":["https://github.com/sponsors/fastify","https://opencollective.com/fastify"],"categories":["\u003ch2 align=\"center\"\u003eAwesome Fastify\u003c/h2\u003e"],"sub_categories":["\u003ch2 align=\"center\"\u003eEcosystem\u003c/h2\u003e"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Ffastify-postgres","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffastify%2Ffastify-postgres","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffastify%2Ffastify-postgres/lists"}