プラグイン
プラグイン
Fastifyでは、プラグインを使用して機能を拡張できます。プラグインは、ルートのセット、サーバーデコレーター、またはその他何でも構いません。1つ以上のプラグインを使用するために必要なAPIは、register
です。
デフォルトでは、register
は*新しいスコープ*を作成します。これは、Fastifyインスタンスに(decorate
を介して)変更を加えた場合、この変更は現在のコンテキストの祖先には反映されず、子孫にのみ反映されることを意味します。この機能により、プラグインの*カプセル化*と*継承*を実現できます。このようにして、*有向非巡回グラフ*(DAG)を作成し、相互依存関係によって発生する問題を回避します。
はじめにガイドで、このAPIがいかに使いやすいかを既にご覧になっているかもしれません。
fastify.register(plugin, [options])
プラグインオプション
fastify.register
のオプションのoptions
パラメータは、プラグインがfastify-pluginでラップされていない限り、Fastify自体が使用する定義済みオプションのセットをサポートします。このオプションオブジェクトは、プラグインがラップされているかどうかに関係なく、呼び出し時にプラグインに渡されます。現在サポートされているFastify固有のオプションのリストは次のとおりです。
注:これらのオプションは、fastify-pluginで使用すると無視されます。
Fastifyが将来他のオプションを直接サポートする可能性があります。したがって、衝突を避けるために、プラグインはオプションの名前空間を検討する必要があります。たとえば、プラグインfoo
は次のように登録される場合があります。
fastify.register(require('fastify-foo'), {
prefix: '/foo',
foo: {
fooOption1: 'value',
fooOption2: 'value'
}
})
衝突が懸念事項でない場合、プラグインはオプションオブジェクトをそのまま受け入れることができます。
fastify.register(require('fastify-foo'), {
prefix: '/foo',
fooOption1: 'value',
fooOption2: 'value'
})
options
パラメータは、プラグインの登録時に評価されるFunction
にすることもできます。最初の位置引数を使用してFastifyインスタンスにアクセスできます。
const fp = require('fastify-plugin')
fastify.register(fp((fastify, opts, done) => {
fastify.decorate('foo_bar', { hello: 'world' })
done()
}))
// The opts argument of fastify-foo will be { hello: 'world' }
fastify.register(require('fastify-foo'), parent => parent.foo_bar)
関数に渡されるFastifyインスタンスは、プラグインが宣言された**外部Fastifyインスタンス**の最新の状態であり、**登録順**に従って、先行するプラグインによってdecorate
を介して注入された変数にアクセスできます。これは、プラグインが先行するプラグインによってFastifyインスタンスに加えられた変更に依存する場合に役立ちます。たとえば、既存のデータベース接続を利用してそれをラップする場合です。
関数に渡されるFastifyインスタンスは、プラグインに渡されるインスタンス、つまり参照ではなく外部Fastifyインスタンスのコピーと同じであることに注意してください。インスタンスの使用は、プラグイン関数内で呼び出された場合と同じように動作します。たとえば、decorate
が呼び出された場合、fastify-plugin
でラップされていない限り、デコレートされた変数はプラグイン関数内で使用できます。
ルートプレフィックスオプション
キーprefix
とstring
値を持つオプションを渡すと、Fastifyはそれをregister内のすべてのルートのプレフィックスとして使用します。詳細については、こちらを確認してください。
ルートをfastify-plugin
でラップすると、このオプションは機能しないことに注意してください(回避策があります)。
エラー処理
エラー処理はavvioによって行われます。
一般的なルールとして、次のafter
またはready
ブロックでエラーを処理することを強くお勧めします。そうでない場合、listen
コールバック内でエラーが発生します。
fastify.register(require('my-plugin'))
// `after` will be executed once
// the previous declared `register` has finished
fastify.after(err => console.log(err))
// `ready` will be executed once all the registers declared
// have finished their execution
fastify.ready(err => console.log(err))
// `listen` is a special ready,
// so it behaves in the same way
fastify.listen({ port: 3000 }, (err, address) => {
if (err) console.log(err)
})
async/await
after
、ready
、listen
、そしてThenableであるfastify
は、*async/await*をサポートしています。
await fastify.register(require('my-plugin'))
await fastify.after()
await fastify.ready()
await fastify.listen({ port: 3000 })
注:プラグインの登録時にawait
を使用すると、プラグインと基盤となる依存関係ツリーがロードされ、カプセル化プロセスが「完了」します。プラグインとその依存関係がロードされた後にプラグインに変更を加えても、親インスタンスには反映されません。
ESMサポート
ESMは、Node.js v13.3.0
以降でもサポートされています!
// main.mjs
import Fastify from 'fastify'
const fastify = Fastify()
fastify.register(import('./plugin.mjs'))
fastify.listen({ port: 3000 }, console.log)
// plugin.mjs
async function plugin (fastify, opts) {
fastify.get('/', async (req, reply) => {
return { hello: 'world' }
})
}
export default plugin
プラグインを作成する
プラグインの作成は非常に簡単です。3つのパラメータ(fastify
インスタンス、options
オブジェクト、およびdone
コールバック)をとる関数を作成するだけです。
例
module.exports = function (fastify, opts, done) {
fastify.decorate('utility', function () {})
fastify.get('/', handler)
done()
}
別のregister
内でregister
を使用することもできます。
module.exports = function (fastify, opts, done) {
fastify.decorate('utility', function () {})
fastify.get('/', handler)
fastify.register(require('./other-plugin'))
done()
}
サーバーが閉じようとしているときに知る必要がある場合があります。たとえば、データベースへの接続を閉じる必要があるためです。これがいつ発生するかを知るには、'onClose'
フックを使用できます。
register
は常に新しいFastifyスコープを作成することを忘れないでください。それが 필요ない場合は、次のセクションを読んでください。
スコープを処理する
decorate
でサーバーの機能を拡張するためだけにregister
を使用している場合、Fastifyに新しいスコープを作成しないように指示するのはあなたの責任です。そうでない場合、変更は上位スコープのユーザーがアクセスできません。
新しいコンテキストの作成を回避するためにFastifyに指示する方法は2つあります。
fastify-plugin
モジュールを使用する'skip-override'
hidden propertyを使用する
fastify-plugin
モジュールを使用することをお勧めします。これはこの問題を解決し、プラグインがサポートするFastifyのバージョン範囲をパラメータとして渡すことができるためです.
const fp = require('fastify-plugin')
module.exports = fp(function (fastify, opts, done) {
fastify.decorate('utility', function () {})
done()
}, '0.x')
このモジュールの使用方法の詳細については、fastify-plugin
ドキュメントを確認してください.
fastify-plugin
モジュールを使用しない場合は、'skip-override'
hidden propertyを使用できますが、お勧めしません. 将来Fastify APIが変更された場合、モジュールの更新はあなたの責任になりますが、fastify-plugin
を使用すると、下位互換性について確信できます.
function yourPlugin (fastify, opts, done) {
fastify.decorate('utility', function () {})
done()
}
yourPlugin[Symbol.for('skip-override')] = true
module.exports = yourPlugin