Advanced GraphQL, v2

Adding Subscriptions

Scott Moss

Scott Moss

Superfilter AI
Advanced GraphQL, v2

Check out a free preview of the full Advanced GraphQL, v2 course

The "Adding Subscriptions" Lesson is part of the full, Advanced GraphQL, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Scott explains that subscriptions must be added to a schema like queries and mutations, and a pubsub protocol needs to be set up on the server side.

Preview
Close

Transcript from the "Adding Subscriptions" Lesson

[00:00:00]
>> So subscriptions must be added to your schema, like queries and mutations. Like I said, they are sibling types. So you would make a type for subscriptions, which is a name that graphQL is looking for. Do not rename that as something else until graphQL bought it just call it subscriptions.

[00:00:16]
You need to set up a pub sub protocol server side. So Pub Sub, if you're not familiar with that publish subscribe. Basically a protocol where you can like publish to like a channel. And you can subscribe to that channel to receive whatever you're publishing usually events. So people use like, things like Redis for this or in our example, probably something like in memory.

[00:00:37]
But it's just a place where you can publish events and eventually subscribe to those events. So you had a separate protocol for that server side. Whatever implementation is, and then you have to create the subscription event resolvers you have to create resolvers, just so subscription is a type type definition.

[00:00:54]
And it has fields just like a mutation and queries do. You have to make resolvers for those fields, those fields needs to know what events are they listening for. So you have to make those resolvers for every single field on a subscription that you create otherwise it wouldn't know what to do.

[00:01:11]
And then you need to add any needed authentication in context. So authenticating what subscriptions is gonna be completely different than authenticating with non subscriptions. So we need to address that and handle that. And make sure that you're good to go. Otherwise people can just, I don't know, subscribe to your GraphQL API and not be authenticated, authorized.

[00:01:31]
So if you have authentication authorization, you got to make sure you set that stuff up. And then, of course, there's a client site setup. So if you have a React app or Vue app, it's just, you can't, you have to add some stuff. So what Apollo client there's, you have to add a transport protocol usually like web sockets or it could be polling. Whatever you want, but you have to set it up there.

[00:01:55]
And then usually an application if you're subscribing to something, you probably kick off that subscription early on an application, like maybe in a layout file somewhere that's always active and it's always watching. So when you change routes, that subscription is still watching and maintaining the state. You kick that off before anything else happens.

[00:02:15]
It really depends on your use case. So you want to make sure you set all that up to actually take advantage of subscriptions. Otherwise, why do you have subscriptions? So this is all you need to set up subscriptions. And now I'm going to walk through how to do it.

[00:02:27]
So you can follow along. But if not, don't worry, you're going to be making it on your own right after this. So first thing is, according to this is we need to add subscriptions to our schema like queries and mutations. So I'm going to go down here to our type definitions and my demo file that I have.

[00:02:45]
And I'm at a subscription type. And for this example, we don't really have anything that's meaningful for subscription. So I'll make a new type, and I'll call it item. An item just has a task which is a string Like that. And then what we can do is we can say we want to subscribe to whenever a new type is or new item is created.

[00:03:16]
So we can say new item. We can call this Phil whatever we want, because it's follows the same rules as any other field than any other type. And then it's going to return and item type like that. And then I just need to make a mutation. So when we actually create a type, we can actually create a type which will cause a subscription.

[00:03:34]
So I'll just say, create item that takes in a task which is a string. Like that, that's required. And it's just going to return an item, cool. So the next thing we need to do is, set up pub up protocols. Luckily for us, we get that for free with Apollo server, with this pub sub constructor here.

[00:04:00]
And a pub sub implementation is basically a publish subscribe. Protocol, the pups of thing that they have here is following an interface that you can override and extend with your own capabilities. If you want to use Redis or any other pops up invitation, you can do it or we're going to use theirs for free.

[00:04:15]
So we'll make a new instance of that and we'll call it plug. So equals a new pops up. And then from there, what we need to do is we need to create subscription events and the resolvers. So, for our subscription newItem field we need to make a resolver for it.

[00:04:32]
And the way we can do that, is if we go down to our resolvers objects and sibling of mutation and query, will make one for subscription and for the newItem. Unlike all the other resolvers that you we would right where the resolver is a function that returns something, for subscriptions because there's going to be other options here.

[00:04:53]
Yeah, they haven't objects, in the resolver that you want to write, it's going to be for subscribing to something. So we need to tell the new items subscription, what we're subscribing to. So in this case, we're gonna return a function from the subscribe method on the new item field. And we're gonna use that pub sub,and we are going do something called an a sync iterator.

[00:05:16]
What a key words and async iterator is in JavaScript basically, an iterator that allows you to iterate asynchronously. So you can wait for one thing to process asynchronously before you go to the next one. And this takes either an array of interested triggers that you're interested in or just one and it triggers basically you get together as an event.

[00:05:35]
So what we'll do is we'll make an event on top here and I'm gonna call this event a new item event like this, but the same name. So we got a new item and basically, what I'm saying is the new item subscription is subscribing to any event by the name of new item.

[00:05:57]
So we got that part, and the next part we need to do is add the actual trigger when a new item is created. So we need to go to our mutations, and create a mutations for when we create an item so create an item mutation here. Do that, there's no route arc here.

[00:06:19]
I know it takes in arguments of a task, which will be a string, so I'll get that. And then what I can do is I can just say, right now I'm just going to return an object that represents an item that has a task on it. And but before I do that, what I want to do is I want to publish to our subscription using the same event.

[00:06:41]
So I can say pubsub dot publish. That's going to take a trigger, in this case, the new items. That's what subscribing to. And because subscriptions are only interested in sending and notifying about events. We have to pass the actual data, the payload that we want the subscription to have access to when we create inside of our client.

[00:07:06]
So it has to match exactly what the subscription is referencing. So in this case, an object with a new item field that is an item type. So that's what we'll do. So we'll say, new item. Field with a, item type. So let me just make this available real quick.

[00:07:29]
That, they send an item like that and then we'll just return the item, cool. So we got that stuff setup says here, we also need to add any authentication and context. And this example there's no authentication, but for context, it's very, very similar to what you would normally do.

[00:07:49]
So you have your context object or a context method on the server instance. And you're gonna get an objects here. Normally, we will use something like the requests, like we did an authentication section, but it's also gonna be something here called connection. So if we're using the incoming request is a Subscription is gonna have a connection property.

[00:08:05]
And if there is a connection, then we wanna handle the context creation a little differently. Because the connection is gonna have something on it's called context. So we can get the connection context and pass that around and handle that a little differently than we would non subscription context for authentication.

[00:08:25]
Because we don't have any in this case, you would just use the subscriptions field on this Apollo instance this arguments here, which is an object. And there's a hook for on Connect. On Connect takes a few arguments with the first one that you're going to be interested in are going to be params.

[00:08:40]
Or you might see them refer to this connection params, you can think of these as headers. So if you were to use something like req.header or leave the request object up here and you were looking at the headers to get the auth token. You could think of these params as headers for your subscription.

[00:08:56]
So whatever you pass up on the headers and GraphQL playground is going to be attached to this params object here. So whatever authentication logic you do in the context for a non subscription based request, you can pretty safely do the same thing in the onConnect subscriptions, using the params instead of req.headers.

[00:09:15]
So we got the context set up, we got the params, we got our pubSub. And from here, it's client side setup. We don't have an app right now, but Playground does support Subscriptions luckily for us. So all we have to do is just, for me I am going to start this node server up on 4000.

[00:09:31]
I'm going to go to that URL and get rid of this stuff. So refresh, and let's run a subscription. So first thing is, use the subscription keyword which is normally where you would put query or mutation or just description one. Now, we're going to use a new item.

[00:09:53]
Item is an object type. So we need a sub selection. So I'm going to say it only has a task, I believe, but then I'm gonna hit play. You notice, nothing happening. It's not that the service taking forever and it's hanging. No, it's listening for any subscriptions to come in.

[00:10:08]
So now, we need to actually add some new items that we can see this being published. We can't do this in a new tab in GraphQL playground. Once you have a subscription here, the connection is being taken from that. So we have to add a new browser tab.

[00:10:22]
Go here. And in this case, we'll just go ahead and make a new task. So we'll make a, My 'A' key is so busted, so mutation. And we'll say new or I think it's called create item actually which takes the task. And we can say this is my task, and I'll get the task back.

[00:10:47]
So once I publish that, I get my task back just like it would in a mutation. But then if I go back to this description, you'll see that it showed up here on the right. And if I do another one, That other one also shows up here. And that's basically how subscriptions work.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now