CoolFace
Apppublic

strong-tie/inbound-calls

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
Database.md322 linesDownload Raw Back to Guides
1<h1 align="center">Fastify</h1>2 3## Database4 5Fastify's ecosystem provides a handful of6plugins for connecting to various database engines.7This guide covers engines that have Fastify8plugins maintained within the Fastify organization.9 10> If a plugin for your database of choice does not exist11> you can still use the database as Fastify is database agnostic.12> By following the examples of the database plugins listed in this guide,13> a plugin can be written for the missing database engine.14 15> If you would like to write your own Fastify plugin16> please take a look at the [plugins guide](./Plugins-Guide.md)17 18### [MySQL](https://github.com/fastify/fastify-mysql)19 20Install the plugin by running `npm i @fastify/mysql`.21 22*Usage:*23 24```javascript25const fastify = require('fastify')()26 27fastify.register(require('@fastify/mysql'), {28  connectionString: 'mysql://root@localhost/mysql'29})30 31fastify.get('/user/:id', function(req, reply) {32  fastify.mysql.query(33    'SELECT id, username, hash, salt FROM users WHERE id=?', [req.params.id],34    function onResult (err, result) {35      reply.send(err || result)36    }37  )38})39 40fastify.listen({ port: 3000 }, err => {41  if (err) throw err42  console.log(`server listening on ${fastify.server.address().port}`)43})44```45 46### [Postgres](https://github.com/fastify/fastify-postgres)47Install the plugin by running `npm i pg @fastify/postgres`.48 49*Example*:50 51```javascript52const fastify = require('fastify')()53 54fastify.register(require('@fastify/postgres'), {55  connectionString: 'postgres://postgres@localhost/postgres'56})57 58fastify.get('/user/:id', function (req, reply) {59  fastify.pg.query(60    'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],61    function onResult (err, result) {62      reply.send(err || result)63    }64  )65})66 67fastify.listen({ port: 3000 }, err => {68  if (err) throw err69  console.log(`server listening on ${fastify.server.address().port}`)70})71```72 73### [Redis](https://github.com/fastify/fastify-redis)74Install the plugin by running `npm i @fastify/redis`75 76*Usage:*77 78```javascript79'use strict'80 81const fastify = require('fastify')()82 83fastify.register(require('@fastify/redis'), { host: '127.0.0.1' })84// or85fastify.register(require('@fastify/redis'), { url: 'redis://127.0.0.1', /* other redis options */ })86 87fastify.get('/foo', function (req, reply) {88  const { redis } = fastify89  redis.get(req.query.key, (err, val) => {90    reply.send(err || val)91  })92})93 94fastify.post('/foo', function (req, reply) {95  const { redis } = fastify96  redis.set(req.body.key, req.body.value, (err) => {97    reply.send(err || { status: 'ok' })98  })99})100 101fastify.listen({ port: 3000 }, err => {102  if (err) throw err103  console.log(`server listening on ${fastify.server.address().port}`)104})105```106 107By default `@fastify/redis` doesn't close108the client connection when Fastify server shuts down.109To opt-in to this behavior, register the client like so:110 111```javascript112fastify.register(require('@fastify/redis'), {113  client: redis,114  closeClient: true115})116```117 118### [Mongo](https://github.com/fastify/fastify-mongodb)119Install the plugin by running `npm i @fastify/mongodb`120 121*Usage:*122```javascript123const fastify = require('fastify')()124 125fastify.register(require('@fastify/mongodb'), {126  // force to close the mongodb connection when app stopped127  // the default value is false128  forceClose: true,129 130  url: 'mongodb://mongo/mydb'131})132 133fastify.get('/user/:id', async function (req, reply) {134  // Or this.mongo.client.db('mydb').collection('users')135  const users = this.mongo.db.collection('users')136 137  // if the id is an ObjectId format, you need to create a new ObjectId138  const id = this.mongo.ObjectId(req.params.id)139  try {140    const user = await users.findOne({ id })141    return user142  } catch (err) {143    return err144  }145})146 147fastify.listen({ port: 3000 }, err => {148  if (err) throw err149})150```151 152### [LevelDB](https://github.com/fastify/fastify-leveldb)153Install the plugin by running `npm i @fastify/leveldb`154 155*Usage:*156```javascript157const fastify = require('fastify')()158 159fastify.register(160  require('@fastify/leveldb'),161  { name: 'db' }162)163 164fastify.get('/foo', async function (req, reply) {165  const val = await this.level.db.get(req.query.key)166  return val167})168 169fastify.post('/foo', async function (req, reply) {170  await this.level.db.put(req.body.key, req.body.value)171  return { status: 'ok' }172})173 174fastify.listen({ port: 3000 }, err => {175  if (err) throw err176  console.log(`server listening on ${fastify.server.address().port}`)177})178```179 180### Writing plugin for a database library181We could write a plugin for a database182library too (e.g. Knex, Prisma, or TypeORM).183We will use [Knex](https://knexjs.org/) in our example.184 185```javascript186'use strict'187 188const fp = require('fastify-plugin')189const knex = require('knex')190 191function knexPlugin(fastify, options, done) {192  if(!fastify.knex) {193    const knex = knex(options)194    fastify.decorate('knex', knex)195 196    fastify.addHook('onClose', (fastify, done) => {197      if (fastify.knex === knex) {198        fastify.knex.destroy(done)199      }200    })201  }202 203  done()204}205 206export default fp(knexPlugin, { name: 'fastify-knex-example' })207```208 209### Writing a plugin for a database engine210 211In this example, we will create a basic Fastify MySQL plugin from scratch (it is212a stripped-down example, please use the official plugin in production).213 214```javascript215const fp = require('fastify-plugin')216const mysql = require('mysql2/promise')217 218function fastifyMysql(fastify, options, done) {219  const connection = mysql.createConnection(options)220 221  if (!fastify.mysql) {222    fastify.decorate('mysql', connection)223  }224 225  fastify.addHook('onClose', (fastify, done) => connection.end().then(done).catch(done))226 227  done()228}229 230export default fp(fastifyMysql, { name: 'fastify-mysql-example' })231```232 233### Migrations234 235Database schema migrations are an integral part of database management and236development. Migrations provide a repeatable and testable way to modify a237database's schema and prevent data loss.238 239As stated at the beginning of the guide, Fastify is database agnostic and any240Node.js database migration tool can be used with it. We will give an example of241using [Postgrator](https://www.npmjs.com/package/postgrator) which has support242for Postgres, MySQL, SQL Server and SQLite. For MongoDB migrations, please check243[migrate-mongo](https://www.npmjs.com/package/migrate-mongo).244 245#### [Postgrator](https://www.npmjs.com/package/postgrator)246 247Postgrator is Node.js SQL migration tool that uses a directory of SQL scripts to248alter the database schema. Each file in a migrations folder need to follow the249pattern: ` [version].[action].[optional-description].sql`.250 251**version:** must be an incrementing number (e.g. `001` or a timestamp).252 253**action:** should be `do` or `undo`. `do` implements the version, `undo`254reverts it. Think about it like `up` and `down` in other migration tools.255 256**optional-description** describes which changes migration makes. Although257optional, it should be used for all migrations as it makes it easier for258everyone to know which changes are made in a migration.259 260In our example, we are going to have a single migration that creates a `users`261table and we are going to use `Postgrator` to run the migration.262 263> Run `npm i pg postgrator` to install dependencies needed for the264> example.265 266```sql267// 001.do.create-users-table.sql268CREATE TABLE IF NOT EXISTS users (269  id SERIAL PRIMARY KEY NOT NULL,270  created_at DATE NOT NULL DEFAULT CURRENT_DATE,271  firstName TEXT NOT NULL,272  lastName TEXT NOT NULL273);274```275```javascript276const pg = require('pg')277const Postgrator = require('postgrator')278const path = require('node:path')279 280async function migrate() {281  const client = new pg.Client({282    host: 'localhost',283    port: 5432,284    database: 'example',285    user: 'example',286    password: 'example',287  });288 289  try {290    await client.connect();291 292    const postgrator = new Postgrator({293      migrationPattern: path.join(__dirname, '/migrations/*'),294      driver: 'pg',295      database: 'example',296      schemaTable: 'migrations',297      currentSchema: 'public', // Postgres and MS SQL Server only298      execQuery: (query) => client.query(query),299    });300 301    const result = await postgrator.migrate()302 303    if (result.length === 0) {304      console.log(305        'No migrations run for schema "public". Already at the latest one.'306      )307    }308 309    console.log('Migration done.')310 311    process.exitCode = 0312  } catch(err) {313    console.error(err)314    process.exitCode = 1315  }316 317  await client.end()318}319 320migrate()321```322