Use GraphQL to load from any database in your Meteor app

How to get more control over your data with Apollo

Meteor Development Group calls Apollo, their open source GraphQL client, the spiritual successor to Meteor’s flagship feature: its real-time pub/sub system. As early adopters of GraphQL, and one of the first companies offering professional GraphQL training (including a session in January 2017), we at OK GROW! often get questions about GraphQL and Meteor: Is GraphQL ready for prime time? What about Meteor pub/sub? What is Meteor useful for in a world where data loading is done with Apollo?

We use Meteor in our GraphQL training for the same reason we use Meteor elsewhere: it gets the ceremony of setting up an app out of the way so you can focus on your core business logic. We get a lot of value out of Meteor’s no-configuration build, great developer experience (e.g., meteor shell ), the accounts system, and, yes, pub/sub.

However, we also find GraphQL to be a great way to structure data, and it gives you access to new choices, including new databases, integration of REST APIs, and better control of real-time vs. single-request access to data. We believe that GraphQL is the future of APIs, and we are changing our code to use Apollo where it makes sense.

In this post, I’ll outline how you can add Apollo to your Meteor project, and explore the design decisions, benefits, and trade-offs you’ll run into when using GraphQL in Meteor apps.

Setting the Stage

OK GROW! is a Meteor Prime Partner, and we have done all of our new projects in Meteor for several years. In that time we’ve built relationships in the community and really gotten to know the platform. Meanwhile, Meteor has evolved from a tight-knit but fairly closed ecosystem to something much more open —though this also makes it harder to track. The first really big change in this direction was the move towards npm, with an integration in version 1.3 finally allowing us to join the npm ecosystem with no limitations.

With Apollo, one of the last limitations of Meteor was removed: dependence on MongoDB and the lack of non-real-time data access. Apollo works great with Meteor today, and we recommend that everyone give it a try, and, in some cases, migrate some or all of their data to it.

Meteor Auth with the Apollo Meteor Package

There are two ways to add Apollo to a Meteor project: with the Apollo Meteor package, or on your own. Meteor developers are used to a great developer experience, and so it’s natural to turn to the Apollo Meteor package on github. If you add that to your project, you get a couple of things for free:

If the current user is logged in in Meteor, it will pass the current user’s ID to your resolvers, giving you basic auth with the Meteor accounts system.

It will also pass your login token to GraphiQL, an in-browser IDE for exploring GraphQL. After logging in within your app, queries made on Graphiql will behave exactly as they would from your app, making this a great place for learning and query prototyping.

For example, we can have a user query that accepts no arguments and always returns the current logged-in user. (Here I used Trello oauth, but this works with any accounts setup.)

Here is the resolver that queries the database: the Apollo package adds the current Meteor user’s userId to the execution context .

export const resolvers = {

Query: {

async user(root, args, context) {

if (context.userId) {

return await Meteor.users.findOne(context.userId);

}

return null;

},

}

};

context.userId serves the same purpose as this.userId() in Meteor methods. Note one difference from Meteor code: you never return a cursor, so you must always add fetch() or use findOne() .

This is really the only thing needed to have a good development process with Meteor. Basically, everything else you might want to accomplish with Apollo works with the same resources as any other framework, and that is actually very liberating.

Setting up without the Apollo package

The other way to set it up is to roll your own. You can take full control of your setup and bypass the Apollo package without that much effort. The Apollo package itself just adds a small amount of code (about 200 lines) to add accounts integration to the either the Express or Connect integration. Meteor already uses Connect for its HTTP connections, and Express is compatible with Connect middleware, so both approaches should work. Looking at the Apollo package will give you examples of how to achieve its features, so don’t hesitate to go this route if you need more control or wish to stick to npm packages.

Developing with GraphQL on Meteor

The Apollo package enables a nice way to work with GraphQL:

Set up your app with accounts

Log into your app

Go to /graphiql to build your query in GraphiQL

Copy your working query to your code

Having a place to prototype your data and try your queries live is very powerful, and it fits well with the developer experience that we have come to expect as users of Meteor. Apollo relies on static queries in the GraphQL language, rather than building query objects. This leads to some advantages, but the tooling to get syntax highlighting and linting isn’t mature yet. Graphiql give us those advantages as well as the ability to run queries against the dev server as the logged-in user, so it makes sense to work there. Being able to get a query working before committing it to code is great, and you can simply copy-paste your confirmed code to your app (inside a gql template).

Moving data to GraphQL

Once you have GraphQL in your app, it’s perfectly fine to use both Meteor pub/sub and GraphQL. They don’t conflict at all, and changes made by GraphQL mutations will be reflected in Meteor subscriptions (though not the reverse — read more below). If you use validated methods, you should find it trivial to switch to GraphQL mutations, as methods and mutations are very similar in form and function. If not, migration to validated methods might be a good first step to be ready for the change.

If you are migrating from Meteor pub/sub to GraphQL, you should be aware of a limitation: Changes made by Meteor methods will not update queries in Apollo. Although Apollo uses a client cache in a way that somewhat resembles Meteor minimongo, it is not connected to minimongo at all. It can be disconcerting to lose the automatic updates; you’ll have to refresh the page to see new results. The simplest way to avoid this is to migrate queries after the methods. If you do that, you can incrementally move your app without breaking changes. Another option is to trigger a refetch in Apollo after the method call; you won’t get optimistic updates, but in many cases this will be fine.

Even if you keep Mongo, you will have a new design choice available for your queries. Whereas Meteor pub/sub makes real-time very easy, it can actually make large queries that don’t need real-time more difficult to manage due to performance and lack of control. You will now be able to choose pub/sub for things like chat or system status that benefit from live updates while using one-time queries on large requests that are better done only once and at a specified time.

Should I switch to a different database?

Apollo is database-independent and will let you move something other than MongoDB if you wish. Should you? The answer to that will depend on your needs, but the good news is that GraphQL is a perfect tool for supporting both Mongo and another database, either while you migrate or permanently.

Although Apollo makes it straightforward to add databases other than Mongo, there are some reasons you might choose to not switch yet. One is that the accounts system is still tied to Mongo. Sure, you can set up your own system with something like passport, but the accounts system is just nicer and is still one of the unique features of Meteor that lets you avoid spending time on auth early in your project. If you keep accounts, you are still committed to Mongo, and keeping Mongo means that you can still use Meteor pub/sub if you like.

GraphQL subscriptions vs. Meteor Pub/Sub

GraphQL has held out the promise of subscriptions ever since it was first publicized. A lot of people are wondering if they should stop using Meteor pub/sub entirely.

Why would you keep Meteor pub/sub over GraphQL subscriptions? Again, it’s a design decision. If I had an app with bona fide realtime needs that needed to be deployed today (December 2016), I’d definitely use Meteor pub/sub. It’s mature and well-tested, and it is super easy to set up.

Apollo also supports GraphQL subscriptions, but it’s a new technology with less documentation and few examples to work from, and is likely to have a less stable API. If you want to see the latest code, I’d recommend checking out the GitHunt demo app, which has working subscriptions that you can model off of. I would expect this recommendation to change in the coming months, so this is something to keep an eye on.

When subscriptions appear in the Apollo docs, that will be a sign that it’s ready for more people to try it, but there’s no rush if you don’t have pressing issues. We can expect that it will be a while until GraphQL subscriptions are as easy as Meteor pub/sub.

Conclusion

Meteor continues to be a great platform for web app development, and it’s not standing still; recent performance improvements and features have made a significant impact for us. Hopefully this post will give you the information you need to make decisions about whether/when to begin trying GraphQL with it. I think you’ll find the combination really powerful.

About the author: Robert Dickert is a developer at OK GROW!, a Meteor Prime Partner that builds software and provides training in JavaScript, React, and GraphQL. He has been active in the Meteor community since 2012. OK GROW! will be offering a January GraphQL training seminar in San Francisco.