Pretty straight forward actually. I went with a more elaborate approach of creating a wrapper for NATS so I could create a singleton but the actual implementation is as follows.
I created an events folder to house all of my nats related logic.
In the primary config/functions/bootstrap.js
module.exports = () => {
process.nextTick(async () => {
// use nextTick to ensure that global strapi is available for logging purposes
await natsWrapper.connect(
process.env.clusterId,
process.env.clientId,
process.env.natsUrl
);
// also a good place to initialize listeners if needed
});
};
Then in the events/nats-wrapper.js
const nats = require("node-nats-streaming");
class NatsWrapper {
_client;
get client() {
// ... singleton logic
}
connect(clusterId, clientId, url) {
this._client = nats.connect(clusterId, clientId, { url });
return new Promise((resolve, reject) => {
this.client.on("connect", () => {
// ... if good connection resolve
});
this.client.on("error", (err) => {
// no connection then reject
});
});
}
}
const natsWrapper = new NatsWrapper();
module.exports = natsWrapper;
Then in my case, If I wanted to send an event on entity create or update etc…, I can simply import a publisher in the models lifecycle methods and send it off.
Personally, I use a shared common module that contains core logic for all my services so I can just subclass out listeners or publishers and leave all of the heavy lifting to my module.
This is still very much a WIP but it seems to work well enough.
I am still working on how to perform graceful shutdown and a few other minor things but this seems to work well for me. Best of luck, and let me know if you have any other questions.