Key Takeaways from GraphQL Summit 2017


GraphQL Summit wasn’t about advanced GraphQL: this was cutting-edge GraphQL!
— a GraphQL Summit attendee

GraphQL Summit 2017 — what a blast!

The above quote reflects two awesome aspects of the GraphQL ecosystem:

  • Compared to last year, there were significantly more people at the conference already using GraphQL, including a large number of people using it in production systems.
  • It sounds like people were pretty excited!

I’d like to share five things that stood out to me the most from my conference experience as both, an attendee and a GraphQL trainer.

Schema stitching

There was a bustle of excitement in the air as schema stitching was unveiled during both, the workshop and the conferences. Schema stitching shows promise as a way to structure microservices while having a manageable central API.

We had the opportunity to link an external API to the app’s schema built during the training, which was one of the training exercises that generated the most excitement.

If you are interested in microservices, you should check out this talk by Jason Lengstorf from IBM where he speaks about his solution, GRAMPS, GRaphql Apollo Microservice Pattern Server:

Schema stitching example from our training class

Here is an example of how we stitch our local schema with a remote one to create the final schema used by the app in our Advanced GraphQL workshop:

// define a way to connect to the external GraphQL API
const link = new HttpLink({
  uri: 'https://external-api.com/graphql',
  fetch,
});

// create a remote schema from the external GraphQL API
const remoteSchema = makeRemoteExecutableSchema({
  schema: await introspectSchema(link),
  link,
});

// create the local schema
const localSchema = makeExecutableSchema({ typeDefs, resolvers });

// from a local type, how to access a remote type
const linkSchema = `
  extend type Location {
    weather: Weather
  }
`;

// the schema that we'll serve
const schema = mergeSchemas({
  // all three above schemas together
  schemas: [remoteSchema, localSchema, linkSchema],
  resolvers: mergeInfo => ({
    // specific resolver for the type definition linking the local schema & the remote schema
    Location: {
      weather: {
        fragment:
          'fragment WeatherLocation on Location { longitude latitude }',
        resolve: ({ longitude, latitude }, args, context, info) => {
          return mergeInfo.delegate(
            'query',
            'weather',
            {
              coords: {
                longitude,
                latitude,
              },
            },
            context,
            info
          );
        },
      },
    },
  }),
});

Subscriptions

We’ve been hearing about subscriptions for a while, and they are starting to get real. This talk by Robert Zhu of Facebook covered the subject really well.

There was also a talk on live queries by Rodrigo Muñoz. Live query functionality isn’t there yet, but it’s very promising.

Subscription example from our training class

Here is an example of how we handle subscriptions on the client (from a React Component) in our Advanced GraphQL workshop:

this.props.subscribeToMore({
  // a graphql document (`subscriptions 
  document: LIST_SUBSCRIPTION_UPDATE,
  // how to update the cache when new data comes from the subscriptions
  updateQuery: (prev, { subscriptionData }) => {
    const { placeUpdated } = subscriptionData;

    if (!placeUpdated) {
      return prev;
    }

    const index = prev.places.findIndex(
      place => place.id === placeUpdated.id
    );

    // change the "updated place" in the list of places present in the cache
    return {
      ...prev,
      places: [
        ...prev.places.slice(0, index),
        placeUpdated,
        ...prev.places.slice(index + 1),
      ],
    };
  },
});

Understanding what’s going in your API

With the increased focus on production GraphQL, we saw a lot more interest in understanding what was happening with the GraphQL stack:

  • We noticed in the training that not everyone was using a batching/caching solution for their GraphQL backend. If you aren’t already, we highly recommend dataloader (or a similar tool in your language of choice if you don’t use JavaScript).
  • Apollo proposes a tracing GraphQL extension that profiles all of your graphql operations, supported by many server implementations
  • Apollo Engine is a new commercial product to monitor performance an even add data caching.

To see how some of these concepts come together, you should watch this talk by Sashko Stubailo of the Apollo team:

Apollo Engine setup example

Apollo Engine setup is just a few lines of code for a maximum benefit!

const engine = new Engine({
  engineConfig: {
    apiKey: ENGINE_API_KEY,
    logging: {
      level: 'DEBUG'   // Engine Proxy logging level
    }
  },
  graphqlPort: process.env.PORT
  endpoint: '/graphql',                 
});

app.use('/graphql', bodyParser.json(), graphqlExpress({
  schema,
  context: { /* ... */ },
  // enable tracing extension
  tracing: true,
  cacheControl: true
}));

engine.start();

Apollo Client 2.0

Apollo Client 2.0 takes the most popular client for GraphQL and makes it smaller and more flexible.

The network interface is now built from composable links that can not only control network connections, retries, and errors.

Apollo Client can even store state data in the local cache, potentially even displacing Redux for some developers. It also allows a choice of client cache technologies, which should help for mobile adoption.

James Baxley explains the details in his talk:

// a stateless non-terminating link to make operations aware of the current user token
const authLink = new ApolloLink((operation, forward) => {
  const token = localStorage.getItem('AUTH_TOKEN');

  operation.setContext(() => ({
    headers: {
      authorization: token ? `JWT ${token}` : null,
    },
  }));

  return forward(operation);
});

// links can be composed!
const link = authLink.split(
  // if the operation is a subscription, use the websocket link
  // else use the http link
  // note: implementation not shown in this gist
  hasSubscriptionOperation,
  new WsLink({
    uri: 'ws://localhost:8081/graphql',
    options: { reconnect: true },
  }),
  new HttpLink({ uri: 'http://localhost:8080/graphql' })
);

// a cache independent from Redux
const cache = new InMemoryCache();

const client = new ApolloClient({
  link,
  // we hydrate/restore the cache with an initial state we get from server-side rendering
  cache: cache.restore(window.__APOLLO_STATE__ || {}),
})

Xavier Cazalot (me, the writer! 👋) presenting Apollo Link during the training class

Health of the ecosystem

GraphQL feels like the “real deal” now. We had speakers from the New York Times, Facebook, Twitter, Coursera, Khan Academy, and GitHub, and attendees from Atlassian, Circle CI, Nike and others.

Talk discussions went beyond “what is GraphQL” to how companies are beginning to scale GraphQL:

Conclusion

The GraphQL Summit was an awesome event—full of great people, great discussions and great discoveries. Let’s continue sharing our passion for GraphQL, discover new practices, and keep building great applications.

We have tailored the Advanced GraphQL workshop for this conference and keep making it better, thanks to the attendees’ feedback. We couldn’t have asked for a better group to work with, and look forward to hopefully doing it again next year. In the meantime, if you’re interested in having a GraphQL Training at your office, please get in touch.

30 people learning advanced GraphQL at Apollo’s HQ

A big thank you to MDG for organizing this second edition of GraphQL Summit & to Lee Byron for doing such an amazing job at MCing the event.

We hope to see you all next year at the GraphQL Summit 2018! 🎩

Let's stay connected. Join our monthly newsletter to receive updates on events, training, and helpful articles from our team.