Meteor: using publish-subscribe pattern without MongoDB

Rogério de Oliveira
5 min readApr 5, 2022
All along when people asked me about how publish-subscribe works, I always used a great analogy to explain that: the radios. The radio station would be the publisher and those who were tuning their radios on this radio would be the subscribers.
From the beginning when people asked me about how publish-subscribe worked, I always used a great analogy to explain that: the radios. The radio station would be the publisher, whereas all those who were tuning their radios on that would be the subscribers. Credits: Music Radio Creative.

Motivation

I decided to write this tiny article to make things clear about an issue I faced during my working day when developing a new feature in a Meteor app. It can be described as: using Meteor publish-subscribe mechanism without having a MongoDB instance on the server side. I was working on a controlled rollout of a new feature on a large app and using Unleash as feature management for that. To connect clients to the server, I choose Meteor’s pub-sub mechanism to enable or disable such feature according to my strategy. That concept is summarized in Figure 1.

Figure 1 — Sending an Unleash notification to clients on a Meteor based application via pub-sub mechanism.
Figure 1 — Sending an Unleash notification to clients on a Meteor based application via pub-sub mechanism.

This alternative allowed me to connect the structure in a way the clients could receive the toggle change event as soon as it happened. However, there was a hurdle in my path: I didn’t have any Mongo instance to carry it out as described by Meteor doc.

In general, Meteor’s official documentation is awesome when explaining that by brief examples applied in contexts which assume a MongoDB is present. However, for me it’s not clear enough when you don’t have one. That way, I realized that more effort would be required to accomplish my goal. There wasn’t any way out but digging up across the internet for something useful about that. After checking out bunches of info (official doc, foruns, repositories, etc.), I could finally find a solution by combining all knowledge taken from those sources in something that worked!

At present, I’d like to share what I learnt with those who are coming across or may pass through difficulties like that.

How did I get over it?

Publish-subscribe (our just pub-sub) is a fancy and powerful pattern that allows us to establish a communication channel between the publisher and the subscribers. Likewise other technologies, Mongo has its own pub-sub mechanism using DDP pattern which is built over the web socket protocol. DDP is pretty handy when we want to send some notification from the server to the clients on a Meteor based app.

Usually, Mongo’s pub-sub partner relies on a MongoDB instance on the server side to store and control data, hence you would end up with something like that:

Figure 2 — Usual pub-sub code on the client side.
Figure 2 — Usual pub-sub code — client side.

And finally, on the client side:

Figure 3 — Usual pub-sub code — server side.
Figure 3 — Usual pub-sub code — server side.

Meteor.subscribe() method returns a “subscription handle” with a property called “ready”. This is a reactive function that returns true when the publication is marked as ready or false otherwise (either you call this.ready() explicitly, or the initial contents of a returned cursor are sent over).

Those steps look pretty straightforward and clear unless you don’t have a Mongo environment hooked up to the Meteor server as I mentioned before. If it’s your context, from my previous experience, it may be tricky for you. Fortunately, there is an alternative to get around that.

To be straight, when some Meteor based solution needs to use pub-sub mechanism without a Mongo environment on server side (whatever the reason), we need to do something similar as described by the following snippets:

Server side

Figure 4 — Publish function built over low-level interface.
Figure 4 — Publish function built over low-level interface.

This time, on the server side we no longer need to instantiate a Mongo collection to make that mechanism work. In the example above, I wrote a simple demo in which the publish function directly controls its published record set by calling the functions “added” and “changed” which Mongo Official Doc refers to as the “Low-level” interface. By going this way, it’s important to highlight that we must call the ready() method once the initial record set is complete.

Consequently, this low-level interface provided by the publish function allows to “simulate” part of the automatized Meteor pub-sub mechanism by raising events manually.

Client side

Figure 5 — Client subscription and handling.
Figure 5 — Client subscription and handling.

On the client side, the concept remains almost the same. To illustrate the use of the events thrown manually, the serverEvent var was inserted in the payload to distinguish the incoming server events which in this example are “added” and “changed”. For further details about all available methods take a look at Meteor Pulbish and Subscribe official doc.

Last but not least, if you want to keep exclusive DDP channels between clients and server it’s mandatory to provide some argument to distinguish each other, otherwise Meteor will reuse the same subscription for all of them as disclaimed in official doc:

“[…] If your function subscribes to the same record set (same name and parameters), Meteor is smart enough to skip a wasteful unsubscribe/resubscribe.”

Figure 6 — Isolated subscriptions using uuid as identifier.
Figure 6 — Isolated subscriptions using uuid as identifier.

It makes sense when we’re working with shared channels (broadcast), but not so much when handling exclusive or private ones. In my real scenario, it was necessary to keep exclusive subscriptions for each client once their data were distinct. To ensure that, each client had a unique uuid identifier passed as an argument to the subscribe function. It will instruct Meteor’s mechanism to keep individual topics for each client who is subscribed on the server. The example shown here is quite simple to explain that, although it may be a good start for those who are looking for how to establish isolated pub-sub channels in a Meteor app.

Well, that’s all folks. I hope this brief text can help everyone that’s maintaining or even developing a new Meteor app and needs to work with a pub-sub mechanism without relying on a Mongo instance.

Acknowledgments: Carolina Lordão for the content review.

--

--

Rogério de Oliveira

Postgraduate in Software Architecture - PUC/MG | Computer Engineering - UNIFEI My LinkedIn: https://www.linkedin.com/in/rogerio-oliveirahs/