Real Time GraphQL — Chat (Part 2 Client)

The Final Product

Welcome back. In the last post we setup GraphQL Subscriptions with a little help from 2 Apollo packages:

If you haven’t read that post, it’s a combination of background and server side of the Chatroom we’re building.

All the code for todays section can be found here, clone and star before moving on! :)

We’re going to add real time behavior to a currently non-reactive Message list. Chat is a great example of a product that needs data as fresh as possible.

GraphQL Clients operate across networks (HTTP/WSS) and Apollo Client gives you a configurable piece called the networkInterface. The base network interface is via HTTP, but we are going to add a subscription interface as well.

We’re going to create a base network interface at the /graphql url. Our UI is proxying to the API Server via http-proxy. With the help of subscriptions-transport-ws we create a new SubscriptionClient at the API Server’s web-socket path and addGraphQLSubscriptions to our base network interface.

With that, our GraphQL client can speak over web sockets.

Now remember, subscriptions are another operation type. So we need to create a subscription document:

Here we describe a graphql subscription for messageAdded. All GraphQL Semantics are the same, subscriptions are supported by the language. How cool is that! This subscrption describes data published to the client for messages added to a given chatroomId.

Life Hack: graphql-tag exports a webpack loader so you can write .gql/.graphql files and import them into your React Components.

In my previous post I had expressed that for products with minor “reactive” requirements subscribing to all fields of your data is overkill. With GraphQL subscriptions, we attach our subscriptions to what I like to call “base” queries.

In our example our base query is a static list of all the Messages per given chatroomId:

With newer versions of Apollo Client and React Apollo, the base query returns a method to your Component called subscribeToMore. This was pretty hard for me to grok so let me break it down:

I always use graphql in conjunction with mapProps from Recompose to create a new set of props for my Component. In this case I’m going to get subscribeToMore from the data prop and create a function to use in lifecycle methods to subscribe.

Now that we have a subscribeToMessages function to use, let’s fill in subscribeToMore with the right options.

We need to supply:

  • document: This is the subscription document we create above
  • variables: Need to fulfill the document, our chatroomId
  • onError: MUST LOG ERRORS. PREACH.

Okay this is probably the coolest part of the process. When our subscription sends metadata to the client, Apollo Client receives this data through the subscriptions network interface and is passed to this update function. Here we get to control what is written to our store for the base query. In our case we just want to add the new message to the list of messages in the Chatroom.

Now that we have our subscribe function, let’s initiate it when the component mounts:

Let’s go check out what we see in our Redux Dev Tools!

Here we can see a log of our operations. We make our first query for the messages, then when we addMessage we trigger a mutation. When the mutation finishes creating the message on our backend, the client gets a SUBSCRIPTION_RESULT where Apollo Client will then run updateQuery function to update our message list state.

The Final Product

Conclusion

Checkout everything in action in the API Server and the React App. GraphQL Subscriptions are super exciting and I hope this simple tutorial gets you to want to understand things deeper! Hoping to cover more content on this as I go deeper and deeper into production usage!

If you enjoyed this post, please give it a recommend! Thanks!

Cheers!

Software Engineer at Workpop, Inc.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store