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:
- 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
- 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 😄
So I'm working with
fastifysome 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
tags.js
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-pluginto the rescue! I will create a shared database plugin which will decorate the fastify instance with a db wrapper, use it in my rootserverfile and just use it in all my plugins:server.js
users.js/tags.js
And here my concerns come into play:
fastify-plugin) break encapsulation? It would make sense if I could usefastify-plugindependenciesfield, but nothing like this is available in purefastifyplugins and I have no clear indicator that tells me that I forgot to provide a dependency to the encapsulated pluginSo 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
fastifyinstance? 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 😄