Skip to content

Plugins best practices #1448

@jsardev

Description

@jsardev

So I'm working with fastify some time already and I truly love it! 😄 After some time I came to a reflection about plugins and I'm not sure if I get it right.

Let me explain my case in an example:

My app needs some posts and tags API. These two could be easily separate microservices so I'd like to split them into plugins:

users.js

module.exports = async fastify => {
    const db = somedb('conn.string');
    fastify.get('/users/:id', (request, reply) => {
        // db operations
    });
    // other endpoints
}

tags.js

module.exports = async fastify => {
    const db = somedb('conn.string');
    fastify.get('/tags/:id', (request, reply) => {
        // db operations
    });
    // other endpoints
}

Alright! Everything is cool. But... I duplicate database access code right now, and if I'd like even more plugins I'd duplicate this even more.

fastify-plugin to the rescue! I will create a shared database plugin which will decorate the fastify instance with a db wrapper, use it in my root server file and just use it in all my plugins:

server.js

fastify.register(require('dbplugin'), { connstring: '...' });
fastify.register(require('./users'));
fastify.register(require('./tags'));

users.js/tags.js

module.exports = async fastify => {
    // use fastify.db() here
 }

And here my concerns come into play:

  1. Doesn't relying on shared plugins (via fastify-plugin) break encapsulation? It would make sense if I could use fastify-plugin dependencies field, but nothing like this is available in pure fastify plugins and I have no clear indicator that tells me that I forgot to provide a dependency to the encapsulated plugin
  2. Relying on shared plugins also makes testing harder, as I need to remember and provide all required plugins in the test (with all configurations)

So my question is: is it a better practice to encapsulate every dependency in a plugin, or rather provide all the shared functionality from a higher-level fastify instance? If the latter, then how do I ensure that these dependencies are present (should I do a manual check?)

I hope I've explained my issue well so it's clear. If not, just ask 😄

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleIssue or pr with more than 15 days of inactivity.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions