メインコンテンツへスキップ
バージョン: latest (v5.0.x)

データベース

データベース

Fastifyのエコシステムは、さまざまなデータベースエンジンに接続するための多数のプラグインを提供しています。このガイドでは、Fastify組織内で管理されているFastifyプラグインがあるエンジンについて説明します。

選択したデータベースのプラグインが存在しない場合でも、Fastifyはデータベースに依存しないため、データベースを使用できます。このガイドにリストされているデータベースプラグインの例に従うことで、欠落しているデータベースエンジン用のプラグインを作成できます。

独自のFastifyプラグインを作成する場合は、プラグインガイドをご覧ください。

MySQL

npm i @fastify/mysqlを実行してプラグインをインストールします。

使用方法

const fastify = require('fastify')()

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

fastify.get('/user/:id', function(req, reply) {
fastify.mysql.query(
'SELECT id, username, hash, salt FROM users WHERE id=?', [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}`)
})

Postgres

npm i pg @fastify/postgresを実行してプラグインをインストールします。

:

const fastify = require('fastify')()

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

fastify.get('/user/:id', function (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}`)
})

Redis

npm i @fastify/redisを実行してプラグインをインストールします

使用方法

'use strict'

const fastify = require('fastify')()

fastify.register(require('@fastify/redis'), { host: '127.0.0.1' })
// or
fastify.register(require('@fastify/redis'), { url: 'redis://127.0.0.1', /* other redis options */ })

fastify.get('/foo', function (req, reply) {
const { redis } = fastify
redis.get(req.query.key, (err, val) => {
reply.send(err || val)
})
})

fastify.post('/foo', function (req, reply) {
const { redis } = fastify
redis.set(req.body.key, req.body.value, (err) => {
reply.send(err || { status: 'ok' })
})
})

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

デフォルトでは、@fastify/redisはFastifyサーバーがシャットダウンしてもクライアント接続を閉じません。この動作を有効にするには、次のようにクライアントを登録します

fastify.register(require('@fastify/redis'), {
client: redis,
closeClient: true
})

Mongo

npm i @fastify/mongodbを実行してプラグインをインストールします

使用方法

const fastify = require('fastify')()

fastify.register(require('@fastify/mongodb'), {
// force to close the mongodb connection when app stopped
// the default value is false
forceClose: true,

url: 'mongodb://mongo/mydb'
})

fastify.get('/user/:id', async function (req, reply) {
// Or this.mongo.client.db('mydb').collection('users')
const users = this.mongo.db.collection('users')

// if the id is an ObjectId format, you need to create a new ObjectId
const id = this.mongo.ObjectId(req.params.id)
try {
const user = await users.findOne({ id })
return user
} catch (err) {
return err
}
})

fastify.listen({ port: 3000 }, err => {
if (err) throw err
})

LevelDB

npm i @fastify/leveldbを実行してプラグインをインストールします

使用方法

const fastify = require('fastify')()

fastify.register(
require('@fastify/leveldb'),
{ name: 'db' }
)

fastify.get('/foo', async function (req, reply) {
const val = await this.level.db.get(req.query.key)
return val
})

fastify.post('/foo', async function (req, reply) {
await this.level.db.put(req.body.key, req.body.value)
return { status: 'ok' }
})

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

データベースライブラリのプラグインの作成

データベースライブラリ(例:Knex、Prisma、またはTypeORM)用のプラグインも作成できます。この例では、Knexを使用します。

'use strict'

const fp = require('fastify-plugin')
const knex = require('knex')

function knexPlugin(fastify, options, done) {
if(!fastify.knex) {
const knex = knex(options)
fastify.decorate('knex', knex)

fastify.addHook('onClose', (fastify, done) => {
if (fastify.knex === knex) {
fastify.knex.destroy(done)
}
})
}

done()
}

export default fp(knexPlugin, { name: 'fastify-knex-example' })

データベースエンジンのプラグインの作成

この例では、基本的なFastify MySQLプラグインをゼロから作成します(これは簡略化された例です。本番環境では公式プラグインを使用してください)。

const fp = require('fastify-plugin')
const mysql = require('mysql2/promise')

function fastifyMysql(fastify, options, done) {
const connection = mysql.createConnection(options)

if (!fastify.mysql) {
fastify.decorate('mysql', connection)
}

fastify.addHook('onClose', (fastify, done) => connection.end().then(done).catch(done))

done()
}

export default fp(fastifyMysql, { name: 'fastify-mysql-example' })

マイグレーション

データベーススキーマのマイグレーションは、データベース管理と開発に不可欠な部分です。マイグレーションは、データベースのスキーマを変更し、データ損失を防ぐための、再現可能でテスト可能な方法を提供します。

ガイドの冒頭で述べたように、Fastifyはデータベースに依存せず、任意のNode.jsデータベースマイグレーションツールを使用できます。ここでは、Postgres、MySQL、SQL Server、およびSQLiteをサポートするPostgratorを使用する例を示します。MongoDBのマイグレーションについては、migrate-mongoを確認してください。

Postgrator

Postgratorは、SQLスクリプトのディレクトリを使用してデータベーススキーマを変更するNode.js SQLマイグレーションツールです。マイグレーションフォルダー内の各ファイルは、[バージョン].[アクション].[オプションの説明].sqlというパターンに従う必要があります。

バージョン:は、インクリメントされる数値である必要があります(例:001またはタイムスタンプ)。

アクション:は、doまたはundoである必要があります。doはバージョンを実装し、undoは元に戻します。他のマイグレーションツールでのupおよびdownのように考えてください。

オプションの説明は、どの変更をマイグレーションが行うかを説明します。オプションですが、すべてのマイグレーションで使用する必要があります。これにより、誰もがマイグレーションでどの変更が行われたかを簡単に知ることができます。

この例では、usersテーブルを作成する単一のマイグレーションがあり、Postgratorを使用してマイグレーションを実行します。

npm i pg postgratorを実行して、例に必要な依存関係をインストールします。

// 001.do.create-users-table.sql
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY NOT NULL,
created_at DATE NOT NULL DEFAULT CURRENT_DATE,
firstName TEXT NOT NULL,
lastName TEXT NOT NULL
);
const pg = require('pg')
const Postgrator = require('postgrator')
const path = require('node:path')

async function migrate() {
const client = new pg.Client({
host: 'localhost',
port: 5432,
database: 'example',
user: 'example',
password: 'example',
});

try {
await client.connect();

const postgrator = new Postgrator({
migrationPattern: path.join(__dirname, '/migrations/*'),
driver: 'pg',
database: 'example',
schemaTable: 'migrations',
currentSchema: 'public', // Postgres and MS SQL Server only
execQuery: (query) => client.query(query),
});

const result = await postgrator.migrate()

if (result.length === 0) {
console.log(
'No migrations run for schema "public". Already at the latest one.'
)
}

console.log('Migration done.')

process.exitCode = 0
} catch(err) {
console.error(err)
process.exitCode = 1
}

await client.end()
}

migrate()