---
title: Apollo
order: 15
description: The Apollo data stack for Reactive GraphQL
discourseTopicId: TODO
---
Introduction
Apollo is a GraphQL client/server for transporting data. While it doesn't yet have all the features that Meteor's pub/sub system has, it provides a way to get data from any database – not just MongoDB.
- [Apollo docs](https://www.apollographql.com/docs/)
You can get started with Apollo and Meteor by creating a new Meteor application with the Apollo skeleton:
```shell
meteor create apollo-app --apollo
```
Apollo Client
[Apollo client docs](https://www.apollographql.com/docs/react/)
Getting data
Instead of calling `Meteor.subscribe`, you will use [queries](https://www.apollographql.com/docs/react/data/queries/) to get data.
The main difference with subscriptions is that queries get called only once (by default) and don't get updated data like a subscription would. This is great for data that doesn't change often and where you don't need reactivity.
Changing data
Instead of calling a Meteor method with `Meteor.call`, you use a function called [`mutate`](https://www.apollographql.com/docs/react/data/mutations/) to run a *mutator*, which is GraphQL's equivalent to a method.
Mutators are only run on the server, but they can return an object which then can update the local cache without the need to call a query again.
Apollo Server
[Apollo server docs](https://www.apollographql.com/docs/apollo-server/)
Getting data
Instead of using `Meteor.publish` to define publications, you write [resolve functions](https://www.apollographql.com/docs/apollo-server/data/resolvers/) – called *resolvers* – that fetch different types of data in the query.
Changing data
Instead of using `Meteor.methods` to define methods, you write [mutators](https://www.apollographql.com/docs/tutorial/mutation-resolvers/) – functions that *mutate* (change) data.
These are part of the resolver functions under `Mutation` key.
GraphQL
GraphQL is a query language for apps to get the data they want. Instead of the server deciding what's in a publication, the client uses GraphQL to say exactly which fields of which objects it wants.
- [About GraphQL](https://graphql.org/)
- [Intro to GraphQL](https://medium.com/apollo-stack/the-basics-of-graphql-in-5-links-9e1dc4cac055)
- [GraphQL coming from REST](https://medium.com/apollo-stack/how-do-i-graphql-2fcabfc94a01#.pfdj5bxxj)
Advanced
[Principled GraphQL](https://principledgraphql.com/)
Latency
Meteor publications are blocking by default, whereas multiple GraphQL queries are executed in parallel. Publications stream data to the client as it arrives, whereas all the resolvers in a GraphQL query have to return before the data is sent to the client. (Although GraphQL is discussing adding the ability to stream results to the client as they come in.)
Meteor specific
Meteor has a specific Apollo package which includes user object into the context of a query.
```shell
meteor add apollo
```
On server you import `getUser` function and include it into the context option when setting up Apollo server:
```javascript
import { ApolloServer } from '@apollo/server';
import { WebApp } from 'meteor/webapp';
import { getUser } from 'meteor/apollo';
import typeDefs from '/imports/apollo/schema.graphql';
import { resolvers } from '/server/resolvers';
import express from 'express';
import { expressMiddleware } from '@apollo/server/express4';
import { json } from 'body-parser'
const context = async ({ req }) => ({
user: await getUser(req.headers.authorization)
})
const server = new ApolloServer({
cache: 'bounded',
typeDefs,
resolvers,
});
export async function startApolloServer() {
await server.start();
WebApp.connectHandlers.use(
'/graphql', // Configure the path as you want.
express() // Create new Express router.
.disable('etag') // We don't server GET requests, so there's no need for that.
.disable('x-powered-by') // A small safety measure.
.use(json()) // From `body-parser`.
.use(expressMiddleware(server, { context })), // From `@apollo/server/express4`.
)
}
```
This will make user data available (if user is logged in) as the option in the query:
```javascript
{
Query: {
userUniverses: async (obj, { hideOrgs }, { user }) => {
if (!user) return null
const selector = { userId: user._id, }
if (hideOrgs) selector.organizationId = { $exists: false }
return UniversesCollection.find(selector).fetch()
}
}
}
```
There are many other community packages that provide additional features or makes the initial setup easier, here is an incomplete list of some of them:
* [quave:graphql](https://atmospherejs.com/quave/graphql) - Utility package to create GraphQL setup in a standard way.
* [cultofcoders:apollo](https://atmospherejs.com/cultofcoders/apollo) - Meteor & Apollo integration.
* [cultofcoders:graphql-loader](https://atmospherejs.com/cultofcoders/graphql-loader) - Easily load your GraphQL schema in your Meteor app!
* [cultofcoders:apollo-accounts](https://atmospherejs.com/cultofcoders/apollo-accounts) - Meteor accounts in GraphQL
* [swydo:blaze-apollo](https://atmospherejs.com/swydo/blaze-apollo) - Blaze integration for the Apollo Client
* [swydo:ddp-apollo](https://atmospherejs.com/swydo/ddp-apollo) - DDP link and server for Apollo.