Check out a free preview of the full Advanced GraphQL, v2 course
The "Adding Subscriptions Solution" 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 live codes the solution to the adding subscriptions exercise.
Transcript from the "Adding Subscriptions Solution" Lesson
[00:00:00]
>> So first thing is we need to go to our type darts and create a new type called subscription. And we'll call this a new post and it's going to have a post type That's the first thing, then we go into our resolvers. And we'll import in the [INAUDIBLE] implementation from Apollo server.
[00:00:36]
Man, there we go. And from, not Apollo server. PubSub, we'll make a new instance. So, Like that no options needed. And from there we need to find our mutation where we're creating a post, which is here and you can see it's already using the pubsub.publish with new posts and it's passing that post.
[00:01:06]
So we're good there. So the only thing we need to do-
>> You might want to camel case that.
>> Camel case which one?
>> PubSub.
>> PubSub, there we go. Thank you. Did I do that up here? Yes I did. Thank you. So, you got your publish.
[00:01:21]
You're adding the event, and then you're adding the pay low. The next thing we need to do is head over to creating resolvers for the subscription field that we created on the type deaths, in my case, its new post. So I'm going to make a resolver for subscription, new posts.
[00:01:38]
So I'm out here on my resolvers Phil for a subscription. And I want one for newPost, cuz it's description as an object as a subscribe(), Method like that. And then we're gonna use pubSub.asyncIterator(), and we wanna subscribe to the newPost event. But creating a new post and subscribing to oppose, let's just say that you had to be authenticated for the last one for subscribing, so we need to add some authentication for that.
[00:02:17]
So we'll head over to the index Inside the context. The first thing we need to do is handle the context differently if you're going to be on using subscriptions for the incoming request. So, if context or not that, if connection then what we wanna do is we want to, maybe we still want access to some of this stuff so I'll just make a new context here, like this, and by default, does have all the DB stuff in it.
[00:02:46]
And then if it's a connection, then I'll just return the context plus the connection dot context, spread it over like that. If it's not, then what I'll do is I'll just return a new object with this context, with the user and create token. So if connection, make a whole new context object that has the database stuff on it, plus whatever context the connection has, if not, then we're gonna do what we already had.
[00:03:20]
That'll handle the context. The next thing is we need to add authentication. So, I'm gonna have subscriptions here, which is an objects and then on the connects handler, which happens every time you connect, this has to return a truth the value, otherwise it won't really connect. So, I'm gonna get something called params or connection params.
[00:03:39]
You can call wherever you want. And i'm basically just gonna use the same logic I have up here to figure out if you're authenticated or not. So I can say, token instead of headers. I can just say params. That authorization. You can call this whatever you want. The difference here is on, express req dot headers and whatever the header is, is always going to be lowercase, no matter what the header is coming in at lowercase is it where's this is going to be explicit.
[00:04:07]
So if you on the client side at authorization, with an uppercase a, it's probably gonna be uppercase a here as well. It's not normalized like headers are. So that's the difference. Take note of that. So maybe because of that distinction, you might call this something else like off token just to differentiate between the two.
[00:04:24]
And then for the user, we have the same thing. And then the difference with this is whatever you return on onConnect, this gets merged with the context object. So if you return an object here, in this case, I want the user, whatever this object is, gets merged whatever the object that's what this context.connection is.
[00:04:42]
It's whatever got returned here. So this context.connection is the result of the onConnect returning something. Everybody follow me? Cool, so now, what we'll do is start this up, let me make sure I don't have anything running, which I do, get rid of that. Start this up. Cool, nothing broke.
[00:05:07]
That's always a good sign. Close one of these refresh. So now if I try to subscribe to newPost like this, and I want to get a post message and ID if I try to, hit play I guess I already have a token in there. Yeah, I got something in here.
[00:05:31]
Let me get rid of this stuff. There we go. So if I hit play that should actually break. I expect that to break right now. Hold up. You're returning an object that's got an undefined parameter inside of it but not throwing, returning falsy.
>> All see, where was that? Where do you see that?
[00:06:01]
>> On Connect?
>> That's
>> Server You're always returning the
>> That's right. That's right. Yeah, I'm always I'm trippin. Yeah, so let's say we wanted to throw a new error. I actually want you all to observe this. Nop, if not user
>> Thrown in there. There we go.
[00:06:31]
Cool. Want you to observe that okay, cool. Let's try that again. Start this up. Try this one more time. And you can see I get the error for not been authenticated. Nope, nope, nope, nope, nope. So, Maybe subscriptions on Connect. Maybe you handed out a little handle that a little differently than you do resolvers.
[00:06:53]
Maybe you always had to be authenticated. And you probably wanna shut it down. So you throw an error. But if you don't wanna globally shut it down and maybe subscriptions you do, then you can do what we did here. So I wanted to make that distinctive point. But cool, we got that.
[00:07:07]
And then now, we can go ahead and try our subscription. So we got the newPost going here, let's start that again, no errors this time. We'll make a new tab, we go to localhost:4000, make a new mutation here. I guess I need to sign up first or. Yeah, I'll just sign up.
[00:07:26]
I don't have a credentials for sign in. So we'll sign up, get a token. Get the inputs call it that the auth. I'll get the token here and then this takes in auth like that, and that's gonna be a sign up input dollar sign like that, it needs to add some variables for the off, which will be an email And a password.
[00:08:04]
And a role. Cool, so we'll sign up. Grab this token here, just like that. And then now, we can do our mutation where we create a post. So mutation NewPost. I think it's called createPost, actually. There we go, createPost, those are inputs. Make a variable for a post, which will be a newPost input.
[00:08:33]
I'm guessing, that's gotta be it. Assign that to the variable here, post and a variable here called posts that takes in a message like this only it takes, hello there at our headers Which is just our token that we have here and we should be able to create a post.
[00:09:00]
So we'll do that. Well, so post created if we go back to the playground, you can see I'm getting Nope, nope. Wait, hold on. Why is this thing never scroll? I don't like things never scroll. But the reason we're not getting here is because we haven't sent up the auth token on the subscription side, so it doesn't even have a user anything like that.
[00:09:21]
So we have to send that up. So now we got to do ops not that. Let's restart this, there we go. So now an HTTP headers here. We have to supply the same thing that we had on the index, which was auth token. So we have to supply an auth token which is the same auth token that we had before.
[00:09:43]
So we'll say auth token like this. Paste in that JWT we got that. Hit the subscribe. Now if we hit play on this, we go back, we get the message. So if I do another one. Another one there, we get another message. I like it. So you can use like socket IO for this stuff to like, I guess any transport any protocol works.
[00:10:14]
So it's pretty flexible. Whatever you want to use.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops