Smarter Publish & Subscribe With SmartQuery

Removing autopublish and having to actually understand Meteor’s publish & subscribe model has always been one of the first big roadblocks for new Meteor developers. So this got me thinking about a simpler way to handle pub/sub.

The result is SmartQuery, a simple package that creates your publications and subscriptions for you:

https://www.discovermeteor.com/blog/smarter-publish-subscribe-with-smartquery/

This is just an experiment at this point, but I’d be curious to get people’s feedback! Do you think it’s an interesting direction to explore?

3 Likes

Love it! I’d like to see how this makes some of the recommendations in the meteor guide simpler. @tmeasday is doing the data loading chapter, so he’d be the one to talk to.

Wow! This looks great. My feedback is, call it experiment no more and put it on the path to release v1.0. :slight_smile:

Haha, believe it or not Sacha and I have discussed this in some detail already @sashko! :smile: [1]

What in particular were you thinking that would make sense to take from this in to the article?

I personally think some kind of data structure to wrap a publication’s query in so you can ensure you run the same query on client and server could be useful, but I think we talked about it and there were a bunch of complexities to it (like what happens when you go beyond the very simple one-collection use cases?) so we decided to defer it for this version of the guide (and spend our “political capital” on the Method class). Honestly, I’m increasingly convinced in a client-side mergebox and subscription.documents() is the better long term solution.

The “relay-ish” idea of the client specifying it’s own data and the server simply checking permissions is interesting but ultimately:
a) we wouldn’t recommend it in the guide at this stage,
b) I don’t actually know if it gains you all that much over just putting the query you use for the pub + client side code in a common spot. If the query was dynamically generated (think Relay), it’d be a different story though. But that’s not what Sacha is doing here (perhaps his technique could be extended to do so though?)

[1] See what I did there in writing a vaguely snarky comment and ending it with a smiley face?

1 Like

Thanks! To be honest the main thing this needs to be more than an “experiment” is for other people to use it/look at it. So I’m glad you think it’s interesting!

I thought about this after you suggested it, but in the end it still requires you to define something in one place, and then refer to it from another, and also made passing dynamic arguments a lot more complex. I like the simplicity of the current system where you do everything on the client.

This reminds me of our bizarrre experimental package ezPublish: https://atmospherejs.com/q42/ezpublish. The idea was to control publications from the client :smiley: A terrible idea in public-facing production apps, but really useful for some of our internal apps where it’s OK if people access the entire database.

@sashko, et. al I think I’m missing how in typical production projects this leads to less code, or is even really easier to understand. You will always be writing access control logic for publications and there’s no significant difference here.

I see that I don’t need to define selectors and maybe options twice, but there’s not less code. And as @teamsday mentioned, just like anything else you want to dry up, put it in a common place if it’s complex.

It would be interesting if the core publish api had an explict before hook for auth, maybe.

If we’re talking about shortcuts/encouraging patterns/making things obvious, what would be lovely is if in Blaze you could do something like:

Template.Posts.subscriptions({
    "nameOfSubscription": function () { thatReactivelyReturnsParamsToCallOnTheSubscription }
});

// or in the simple case

Template.Posts.subscriptions(["nameOfSubscription"]);

instead of

Template.Posts.onCreated(function(){
    var tmpl = this;
    tmpl.autorun(function(){
          var parameter = reactivelyGetSomeData;
          tmpl.subscribe("publication", parameter);
    });
});

The totalCount and hasMore are cool features, but IMHO belong in a pagination package. 80% of the time I’m not paginating data in production apps.

Hope that helps point out some opportunities!

I think the logic/mental model might be a bit easier to understand? Instead of a three-step process (publish, subscribe, query), it’s a two-step one (query, define rules).