By default, register
creates a new scope, this means that if you make some changes to the Fastify instance (via decorate
), this change will not be reflected by the current context ancestors, but only to its descendants. This feature allows us to achieve plugin encapsulation and inheritance, in this way we create a direct acyclic graph (DAG) and we will not have issues caused by cross dependencies.
You already see in the section how using this API is pretty straightforward.
The optional options
parameter for fastify.register
supports a predefined set of options that Fastify itself will use, except when the plugin has been wrapped with fastify-plugin. This options object will also be passed to the plugin upon invocation, regardless of whether or not the plugin has been wrapped. The currently supported list of Fastify specific options is:
Note: Those options will be ignored when used with fastify-plugin
It is possible that Fastify will directly support other options in the future. Thus, to avoid collisions, a plugin should consider namespacing its options. For example, a plugin foo
might be registered like so:
fastify.register(require('fastify-foo'), {
prefix: '/foo',
foo: {
fooOption1: 'value',
fooOption2: 'value'
}
})
If collisions are not a concern, the plugin may simply accept the options object as-is:
fastify.register(require('fastify-foo'), {
prefix: '/foo',
fooOption1: 'value',
fooOption2: 'value'
})
The options
parameter can also be a Function
that will be evaluated at the time the plugin is registered while giving access to the Fastify instance via the first positional argument:
Keep in mind that the Fastify instance passed on to the function is the same as the one that will be passed into the plugin, a copy of the external Fastify instance rather than a reference. Any usage of the instance will behave the same as it would if called within the plugins function i.e. if decorate
is called, the decorated variables will be available within the plugins function unless it was wrapped with fastify-plugin.
Route Prefixing option
If you pass an option with the key prefix
with a string
value, Fastify will use it to prefix all the routes inside the register, for more info check here.
Be aware that if you use this option will not work.
Error handling
The error handling is done by .
As a general rule, it is highly recommended that you handle your errors in the next after
or ready
block, otherwise you will get them inside the listen
callback.
// 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(3000, (err, address) => {
if (err) console.log(err)
})
async/await is supported by after
, ready
and listen
, as well as fastify
being a Thenable.
await fastify.register(require('my-plugin'))
await fastify.after()
await fastify.ready()
await fastify.listen(3000)
ESM support
ESM is supported as well from Node.js v13.3.0 and above!
Example:
module.exports = function (fastify, opts, done) {
fastify.get('/', handler)
done()
}
You can also use register
inside another register
:
module.exports = function (fastify, opts, done) {
fastify.decorate('utility', () => {})
fastify.get('/', handler)
fastify.register(require('./other-plugin'))
done()
}
Sometimes, you will need to know when the server is about to close, for example, because you must close a connection to a database. To know when this is going to happen, you can use the hook.
Do not forget that register
will always create a new Fastify scope, if you do not need that, read the following section.
If you are using register
only for extending the functionality of the server with decorate, it is your responsibility to tell Fastify not to create a new scope. Otherwise, your changes will not be accessible by the user in the upper scope.
You have two ways to tell Fastify to avoid the creation of a new context:
- Use the module
- Use the
'skip-override'
hidden property
We recommend using the fastify-plugin
module, because it solves this problem for you, and you can pass a version range of Fastify as a parameter that your plugin will support.
If you do not use the fastify-plugin
module, you can use the 'skip-override'
hidden property, but we do not recommend it. If in the future the Fastify API changes it will be your responsibility to update the module, while if you use fastify-plugin
, you can be sure about backward compatibility.
function yourPlugin (fastify, opts, done) {
fastify.decorate('utility', () => {})
done()
}
module.exports = yourPlugin