Strapi and Nats Streaming Server (pub/sub messaging)

System Information
  • Strapi Version: 3.4.0
  • Operating System: strapi/strapi docker/node:12
  • Database: Postgres
  • Node Version: 12.12.0
  • NPM Version:
  • Yarn Version:

Hello, I am using Strapi for the first time and I am looking for advice on how I would go about integrating Strapi into my message queue. My search through the forums didn’t yield any results or anything similar.

My goal, if possible, is to send events on changes like content-type update, addition, etc… Likewise, I would like to listen for events from my other services and make changes to content-types appropriately.

Any guidance is appreciated.

edit: After some reading, it looks like I can use the lifecycle methods in the models to perform the publishes to my message queue.(correct me if I am wrong, or this is not best practice). Now I am just curious how I can establish the connection to the messaging queue on strapi startup.

edit2: After more reading, it looks like I can use bootstrap to connect to the message queue on startup.

Still open to any advice.

I was able to get this working using the bootstrap method to initialize the connection to Nats. Likewise listening and publishing events on entity actions through the models. It works similarly to implementations. For anyone that needs to do something similar, feel free to dm me.

Am curious as to how you did this. Are you able to post your code somewhere ?

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(

// also a good place to initialize listeners if needed

Then in the events/nats-wrapper.js

const nats = require("node-nats-streaming");

class NatsWrapper {

  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.

1 Like