In Javascript, everything is an object. Similarly, everything in Fastify is a plugin. Basically, plugins form the backbone of Fastify. And hence, it is very important to understand the basics of the Fastify Plugin System.

If you are new to Fastify, it would be better to start with the post on Fastify Server Setup. Else you can continue with this one.

1 – What are Fastify Plugins?

Fastify allows the user to extend its functionalities with plugins. A plugin can be a set of routes, a server decorator, or any thing else.

Fastify provides a well-defined API to work with the plugin system. Using the API, Fastify lets us add our dependencies to the Fastify instance and use them wherever we have access to that instance.

Basically, a plugin is just a function that takes in fastify and options as inputs. Below is how a Fastify plugin looks like:

function pluginA(fastify, options, done) {
   //...
   done()
}

Fastify also supports async plugin.

async function pluginA(fastify, options, done) {
   //...
   done()
}

Here, fastify is the instance and options is the object we can pass to the plugin. Lastly, done is the function we need to call when the job of a plugin is complete. Inside a plugin, we can perform various actions such as registering a route or declaring a utility. We can even have nested registers. Only thing to remember is calling the done function at the end.

2 – Fastify Plugin System – Register & Decorate APIs

Fastify Register is an API that allows the use of one or more plugins. We inject a Fastify instance to the register() method. By default, register() creates a new scope. Basically, this feature allows us to have plugin encapsulation and inheritance.

Let us see an example of how to register a plugin using Fastify’s register() API.

fastify.register(function pluginA(fastify, options, done) {
    fastify.decorate('util', (a, b) => a+b)
    console.log(fastify.util('Hello,', 'World'))

    done()
})

While register() allows us to create a new plugin, the Fastify decorate() API helps us add more functionality to the Fastify instance.

In the above snippet, we add a utility function to the Fastify instance using fastify.decorate(). We can then use the utility by calling fastify.util().

However, the concept of encapsulation means that anything we add to the Fastify instance within the plugin is only available in that same plugin. If we try to access it in another plugin, we get an error.

See below example where we try to access the utility in another plugin.

fastify.register(function pluginA(fastify, options, done) {
    fastify.decorate('util', (a, b) => a+b)
    console.log(fastify.util('Hello,', 'World'))

    done()
})

fastify.register(function pluginB(fastify, options, done) {
    console.log(fastify.util('Test', 'Plugin'))
})

In this case, we will get an error as below because util is not available in pluginB.

console.log(fastify.util('Test', 'Plugin'))
                        ^

TypeError: fastify.util is not a function
    at pluginB (/Users/saurabhdashora/FastifyProjects/fastify-demo-app/index.js:16:25)
    at Plugin.exec (/Users/saurabhdashora/FastifyProjects/fastify-demo-app/node_modules/avvio/plugin.js:132:19)
    at Boot.loadPlugin (/Users/saurabhdashora/FastifyProjects/fastify-demo-app/node_modules/avvio/plugin.js:274:10)
    at processTicksAndRejections (internal/process/task_queues.js:82:21)

Note that Fastify plugin encapsulation applies to ancestors or siblings and not to children. Children will inherit the utility function. See below example:

fastify.register(function pluginA(fastify, options, done) {
    fastify.decorate('util', (a, b) => a+b)
    console.log(fastify.util('Hello,', 'World'))

    fastify.register((fastify, opts, done) => {
      console.log(fastify.util('Inheritance', 'Proved'))
      done()
    })
    done()
})

This will work fine because the children will get access to the utility function.

Conclusion

Encapsulation is a key aspect of the Fastify Plugin System. By using register() and decorate(), we can create a new plugin and add new functionality to Fastify app. At the same time, we are able to encapsulate the new functionality to specific plugins.

Want to build a bigger application using Fastify? Check out this post on building a Fastify REST API.

If you have any comments or queries about this post, please feel free to mention them in the comments section below.

Categories: BlogFastify

Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *