GraphQL Subscriptions with Nexus and React Apollo
Tags: graphql, react, nexus, subscriptions
Published: 2019-06-28 18:23:12

---
title: GraphQL Subscriptions with Nexus and React Apollo
published: true
description: In this tutorial, we are going to create a minimal real-time chat application using GraphQL Nexus and React Apollo. Hopefully by the end of this, you’ll be a pro at using subscriptions.
tags: GraphQL, React, Nexus, Subscriptions
---
#### Introduction

Subscriptions are a very powerful feature of GraphQL. They allow you to have a real-time connection to your database, notifying and updating your data when there are changes. Subscriptions have tons of applications, such as real-time chat applications or live comment feeds on articles.

In this tutorial, we are going to create a minimal real-time chat application using GraphQL Nexus and React Apollo. Hopefully by the end of this, you’ll be a pro at using subscriptions.

![dev.to1](https://cdn-images-1.medium.com/max/800/0*Dne-esyq4HBFU25p) 

#### Meat and Potatoes 

##### Getting Set Up

To get started, download this repository: [https://github.com/hkyang995/graphql-nexus-subscription-starter-backend](https://github.com/hkyang995/graphql-nexus-subscription-starter-backend)

This project contains a schema with a single 

`Post` type- `Post` has two fields, `author` and `content`. We will set up a subscription to update a live chat feed with every new post that is made.

If you take a peek at `src/schema.ts`, you’ll see two queries, 

`post` and `posts`. The `post` query returns the single most recent post, while `posts` returns every post in the database. And as you might have guessed, the `createPost` mutation creates a post.

Let’s get started by installing our tools: GraphQL Yoga, GraphQL Nexus, and GraphQL. We’ll be using Prisma’s demo servers to help get things set up and conveniently host all of our information. The starter file uses yarn to tie our dependencies together, so all we need to do is:  

`yarn`

To start the server at any time during the tutorial, use:

`yarn dev`

Now that we’ve installed everything, we can create a server with Prisma using:

`prisma init`

This command will walk us through the creation of the server. Feel free to choose whatever suits your needs, but for simplicity’s sake, these options will do just fine:

- Demo server
- Choose EU or US
- Name your shiny new service
- Choose a name for this stage (just the default is fine)
- Choose Typescript for our language of choice

Your server will be good to go after running `prisma generate`.

Now we’re finally ready to dive into making our Subscription!

##### Creating the Subscription on the Backend

#### 

Now that we are set up, we are ready to create our Subscription. Since each Subscription needs to return a payload (the bundle of information sent back to you), we’ll add a payload type to our schema.

```
const PostSubscriptionPayload = objectType({
 name: "PostSubscriptionPayload",
 definition(t) {
   t.field("node", {
     type: Post,
     nullable: true
   });
   t.list.string("updatedFields", { nullable: true });
 }
});
```

Like mentioned above, this payload type is the object type that will be returned from our subscription. The key item that we’re going to be looking at is `t.field(“node”)`. We set its type to `Post` so it’ll return exactly what we need, a `Post`!

```
const messageSubscription = subscriptionField("post", {
 type: PostSubscriptionPayload,
 subscribe: (root, args, context) => {
   return context.prisma.$subscribe.post({ mutation_in: "CREATED" }) as any;
 },
 resolve: payload => {
   return payload;
 }
});
```
Here’s the function that’s going to be doing most of the work. You might be thinking, “That’s it??” and yes, that is it! You don’t need anything else on the backend for this particular application.

Here’s how this code works. We set the type to `PostSubscriptionPayload` to return our post. You can see that we pass in an argument to the post `mutation_in: ‘CREATED’`, which means that we’re only going to subscribe to newly created posts (as opposed to posts that are edited or deleted). Finally, we return the payload which completes our Subscription!

You can test this out on your GraphQL Playground by starting it up with `yarn dev`. When you run the Subscription, it will start listening for new posts. When you create a new post using the `createPost` mutation, you’ll be able to see it in your Subscription’s tab.

![gif](https://cdn-images-1.medium.com/max/800/0*gwZc8WUltvUsKQgH)

You can check out and download the completed backend code here:

[https://github.com/hkyang995/graphql-nexus-subscription-starter-backend/tree/completed](https://github.com/hkyang995/graphql-nexus-subscription-starter-backend/tree/completed)

##### Creating the Subscription on the Frontend

We have our subscriptions working on the backend, but we’re not out of the woods yet. The next steps are to make subscriptions work on the frontend so we can see our shiny new `Posts` in real time.

To start out, let’s set up a simple UI and connect our frontend to the backend. To get started, download this repo of frontend code:

[https://github.com/hkyang995/graphql-nexus-subscription-starter-frontend](https://github.com/hkyang995/graphql-nexus-subscription-starter-frontend)

To run the application at any time, use `yarn start` in the command line on the frontend folder.

```
const wsLink = new WebSocketLink({
 uri: `ws://localhost:4000/`,
 options: {
   reconnect: true
 }
});

const httpLink = createHttpLink({
 uri: "http://localhost:4000/"
});

const link = split(
 ({ query }) => {
   const { kind, operation } = getMainDefinition(query);
   return kind === "OperationDefinition" && operation === "subscription";
 },
 wsLink,
 httpLink
);

const client = new ApolloClient({
 link,
 cache: new InMemoryCache()
});
```

If you take a look at `src/App.js`, you’ll see that we’re using Apollo to connect our frontend with our backend. The backend server is set to `localhost:4000`, which can be changed if your server is being hosted elsewhere. We’re also connecting a WebSocket to all of this so we are able to get our subscriptions in real time.

Most of the legwork is being done in our components function, `src/AppContents.js`. In this file, there is a function that takes the input and does a mutation to push the Post to our server. In `src/ChatBox.js`, we query for the `Posts` that already exist and display them to the user.

For now, we can write out messages and submit them, but the chat box won’t update unless we refresh. To fix this, we will set up our Subscription on the frontend.

Using one of our imported packages, `graphql-tag` (`gql`), we can set up a subscription on the frontend like this:

```
const NEW_POST_SUBSCRIPTION = gql`
 subscription PostSubscription {
   post {
     node {
       content
       id
       author
     }
   }
 }
`;
```

Since we defined our subscription on the backend, we only need to specify what we want to grab from it on the frontend. Here we’re getting the content, id, and author.

```
<Query query={GET_EXISTING_POSTS}>
               {({ subscribeToMore, loading, error, data }) => {
```

The `subscribeToMore` function comes packaged in Apollo GraphQL, and is going to be our best friend on the frontend, as it’s going to get our Subscriptions to work. We can pass it through in our query function.

```
<ChatView
  data={data}
  subscribeToMore={() =>
    subscribeToMore({
      document: NEW_POST_SUBSCRIPTION,
      updateQuery: (prev, { subscriptionData }) => {
        if (!subscriptionData.data) return prev;
        const { node } = subscriptionData.data.post;
        return Object.assign({}, prev, {
          posts: [...prev.posts, node]
        });
      }
    })
   }
/>
```

Here, we’re passing the `subscribeToMore` function into our `ChatView` component. Let’s break down how this all works.

We’re passing the subscription into the `document` field, and `updateQuery` is a function that runs every time our query is updated.

```
const { node } = subscriptionData.data.post;
```

We can pull out the node from the subscription data, which contains all of the information about the post: the content, the post id, and the author of the post.

```
return Object.assign({}, prev, {
  posts: [...prev.posts, node]
});
```
At the very end, we’re updating our `posts` by setting it equal to its previous values, along with the new node we got from the subscription.

```
  componentDidMount() {
    this.props.subscribeToMore();
  }
```

The last thing we need to do is add the `subscribeToMore` function into the `ChatView` component’s `componentDidMount` function. This will allow it to update whenever it needs to.

And there you have it! Now whenever a message is sent, your subscription will update the frontend.

The completed code can be found here.

[https://github.com/hkyang995/graphql-nexus-subscription-starter-frontend/tree/completed](https://github.com/hkyang995/graphql-nexus-subscription-starter-frontend/tree/completed)

#### Conclusion

In this tutorial, we built a real-time chat application using GraphQL subscriptions. With this under your belt, subscriptions will appear less daunting for more complex applications.

If you have any questions, comments, concerns, or just want to tell me about your day, feel free to leave a comment. For more content like this, feel free to follow [Novvum](https://twitter.com/novvumio) on Twitter. Thank you!