GraphQL or Meteor methods/pub/sub?

For people who are familiar with both, can you share your experiences?

I’ve been using Meteor for ~5 years now, and I’m very comfortable with meteor pub/sub and methods in blaze. I’ve also about 1 year ago built a new application using React/Redux/REST APIs which just uses Meteor as a build tool. I’m now building a new application and looking at what architecture to use.

The main reason I’m considering GraphQL is to enable reactivity. While probably 75% of my data is static and can be served with REST API or meteor methods, ~25% will be reactive. There will be very little writing of data from the clientside. Almost all of the data will be written into the DB by backend processes, and the client side is mainly a view layer. That said, the data can change rapidly (as often as several hundred inserts / updates a second) and there may be thousands of clients connected at a time.

Meteor pub/sub makes this very easy, but it ties you to MongoDB (I’d prefer using PostgreSQL if possible, although I’m very familiar with Mongo and could use it if necessary), and also to Meteor, making it very difficult to replace Meteor parts in the future if necessary.

On the flip side, I’ve read a bunch about GraphQL including Apollo, Postgraphile, Prisma, Hasura, etc. and it seems like it’s a very heavyweight solution to providing what Meteor does out of the box. I realize that it gives you the power to present a client-side schema that is entirely independent of the actual schema on the server-side DB, but does anyone actually use it this way? That is, Apollo and GraphQL seem like overkill if 90% of your client-side schema is basically your backend DB schema anyway (and the other 10% could be solved with views created in the DB). Solutions like Postgraphile and Hasura basically make this assumption, but then I’m not sure what I’m gaining with all this additional backend stuff I have to maintain vs Meteor publications.

Maybe I just don’t grok the power or reasons behind GraphQL, so I’m interested in people’s experiences using it, particularly if you can compare to using Meteor’s publications. This is the way I see it:

GraphQL Pros: can use Postgresql or any other backend; seems to be an emerging standard so won’t be locked into one platform.

GraphQL Cons: enormous amount of additional boilerplate / backend servers / etc which seems overengineered for the 90% use case of simply presenting the backend DB schema to the frontend with user and access control

Meteor publications Pros: very easy to get started with (especially since I’m already familiar with it)

Meteor publications Cons: locks you into Meteor data access, meteor server, and MongoDB. Possibly performance issues at scale (although helped with solutions like redis-oplog).

Or, for my use case, I could just ditch reactivity, and use frequent polling of a REST API to simulate reactivity. But this seems less elegant and ultimately end up in a lot of duplicated data being sent to each client.

Any thoughts?

1 Like

I switched over to graphql some time ago, so maybe i can help. You already mentioned the important pros/cons. Some comments though:

I realize that it gives you the power to present a client-side schema that is entirely independent of the actual schema on the server-side DB, but does anyone actually use it this way?

yes, very often. In fact that was one important reason for me to no longer use meteor collections. A graphql schema is a better representation of your domain model than a database schema. Meteor collections enforce the db schema onto the client, which is not always suitable. Having a graphql schema between client and server acts like a contract and you can work your way in both direction, from schema to the client-ui and from schema to the database or other data sources. In particular with typescript that reduces errors and makes refactorings much easier, as you can generate types base on the schema

An additional reason by the way for me was the global nature of meteors minimongo collections, which can result in bugs when try to encapsulate data loading into components (when e.g. two subscriptions fetch different subsets of the same collection)

Further, the stronger, but “contracted” separation between client and server makes replacing the ui or adding new clients much easier.

enormous amount of additional boilerplate / backend servers / etc

well… that depends. Writing resolvers is not much different from writing publications and i would argue that there is not much boilerplate going on. There are a lot of short-cuts and advanced setups to try out, but i would go with the bare apollo server first if you want to give it a try.

Possibly performance issues at scale (although helped with solutions like redis-oplog).

I got burned hardly by this. Yes, you can scale meteor, but there are a lot of pitfalls and you might need custom tools like redis-oplog (which also has its own pitfalls). A setup with graphql is “dumber/simpler” (its basically just request/response) and therefore less prone to scaling issues.


concerning reactivity:

this was also a reason why i loved meteor collections with pub/sub. But in reality, its less of a dealbreaker to not have this level of realtime data:

  • what most users expect is that their own changes get reflected everywhere as soon as possible, without delay. Both apollo-client and meteor collections can do this.
  • meteor is additionaly capable of reflecting changes that other users did in realtime. Thats cool, but often not expected. In some cases its even a problem, e.g. when you want to create something like a social media platform and new posts just pop in. Most users want to control when they want to see new content from others. If you don’t need this kind of real-time data, graphql is perfectly fine. You can still do “real time” data by polling (its surprisingly often a good solution) or adding graphql subscriptions (never used it personally)

i think the most important questions are:

  • are other devs working on the project, is the team familiar with the technology?
  • will there be other clients accessing the backend?
  • what is the forseeable future of the project?

Maybe that helps finding the right solution. good luck!

2 Likes

Thanks for your detailed reply! It was really helpful. I took your advice to heart and looked further into graphql solutions.

I’m thinking of using Hasura. While this doesn’t allow me to create an independent schema (it basically takes your Postgres db and creates a 1:1 schema from the db itself), I figure it should be a good way to start and get comfortable with the whole setup. The graphql interface is not public anyway (at this point, at least), so I’d rather start with something reasonable rather than trust my skills writing a brand new schema in a brand new technology :slight_smile:

I looked at reactivity, and basically, it seems there are two concepts in the graphql world:

First is Live Queries, which is essentially polling: you run the query repeatedly, get the full set of results back, and then, the graphql client (like Apollo) figures out what records are updated / new / deleted and updates its local cache. The Pro’s are that the data will always be complete and correct, since it pulls the whole dataset with each query. The Cons are the increased network traffic, and that the diff’ing essentially gets pushed to the client which can be problematic on low-resource platforms like mobile.

Second are subscriptions where you basically subscribe to events, and then, each event gets sent to you as it happens. The Pro’s are much decreased network traffic. The cons are that if you miss an event, you won’t know, so it’s easy to get out of sync with the central data.

What seems to be missing is Meteor’s concept of a subscription, where the server sends you an initial payload to populate your data (like a live query), and then monitors for changes and sends you just the data you need. This seems to combine the best of both worlds: an always-consistent client data cache, with minimal network traffic, at the expense of significant server work that reduces the ability to scale.

Are there any graphql solutions you know of that provides something like Meteor subscriptions? I suppose I could cobble something together, maybe using a query that polls every minute to ensure the cache is consistent, with events through a subscription to keep up with changes between the polling intervals. But I doubt I’d be able to do it better than a library that’s been optimized for it :slight_smile:

it basically takes your Postgres db and creates a 1:1 schema from the db itself

That’s not entirely true. With Hasura you can control the columns (fields) the client can access (based on their roles) and the graphql schema will be generated based on this. You can also extend the schema with SQL functions and actions.
If you’re interested in Hasura, take a look at nhost, it makes things easier (e.g. out of the box authentication and storage).