外掛
外掛
Fastify 允許使用者使用外掛擴展其功能。外掛可以是一組路由、一個伺服器裝飾器,或任何其他東西。您需要使用一個或多個外掛的 API 是 register
。
預設情況下,register
會建立一個新的作用域,這表示如果您對 Fastify 實例進行一些變更(透過 decorate
),此變更不會反映在目前內容的祖先中,而只會反映在其後代中。此功能允許我們實現外掛的封裝和繼承,透過這種方式,我們建立一個有向無環圖 (DAG),並且不會有跨相依性造成的問題。
您可能已經在入門指南中看到使用此 API 是多麼容易
fastify.register(plugin, [options])
外掛選項
fastify.register
的可選 options
參數支援一組預定義的選項,Fastify 本身會使用這些選項,除非外掛已使用 fastify-plugin 包裝。這個選項物件也會在調用時傳遞給外掛,無論外掛是否已包裝。目前支援的 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 將使用它來為註冊內的所有路由加上前綴,有關更多資訊,請參閱此處。
請注意,如果您使用 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
支援async/await,而且 fastify
也是一個 Thenable。
await fastify.register(require('my-plugin'))
await fastify.after()
await fastify.ready()
await fastify.listen({ port: 3000 })
注意:在註冊外掛時使用 await
會載入外掛和底層相依性樹狀結構,從而「最終確定」封裝過程。在載入外掛及其相依性之後對外掛進行的任何變更都不會反映在父實例中。
ESM 支援
從 Node.js v13.3.0
及更高版本也支援 ESM!
// 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
建立外掛
建立外掛非常容易,您只需要建立一個接收三個參數的函式,即 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 作用域,如果您不需要這樣做,請閱讀以下章節。
處理作用域
如果您使用 register
僅是為了使用decorate
擴展伺服器的功能,則您有責任告知 Fastify 不要建立新的作用域。否則,使用者將無法在上層作用域中存取您的變更。
您有兩種方法可以告知 Fastify 避免建立新的內容
- 使用
fastify-plugin
模組 - 使用
'skip-override'
隱藏屬性
我們建議使用 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'
隱藏屬性,但我們不建議這樣做。如果未來 Fastify API 發生變更,您有責任更新模組,而如果您使用 fastify-plugin
,您可以確保向後相容性。
function yourPlugin (fastify, opts, done) {
fastify.decorate('utility', function () {})
done()
}
yourPlugin[Symbol.for('skip-override')] = true
module.exports = yourPlugin