Overview
Now it's time to take care of the resolver for our Subscription
field. This resolver has a special job, along with a special shape. It's a resolver unlike any other! Once we've taken care of the subscription resolver, we need to make sure our mutation is passing along the right data.
🎯 Goal 1: Implement the resolver function for Subscription.listenForMessageInConversation
🎯 Goal 2: Update the resolver function for Mutation.sendMessage
to send the message as the event payload
When your subscription is successfully running, here's what you can expect to see.
The Subscription
resolver
- Start by creating the
Subscription.ts
file in theresolvers
folder. Here's some boilerplate you can use.
import { Resolvers } from "../__generated__/resolvers-types";export const Subscription: Resolvers = {Subscription: {listenForMessageInConversation: {// TODO},},};
- Right away, we can jump into
resolvers/index.ts
and uncomment theSubscription
resolver import so that it's included in our resolvers map.
import { Query } from "./Query";import { Mutation } from "./Mutation";import { Message } from "./Message";import { Conversation } from "./Conversation";import { User } from "./User";import { Subscription } from "./Subscription";const resolvers = {...Query,...Mutation,...Conversation,...Message,...User,...Subscription,};export default resolvers;
- Back in
resolvers/Subscription.ts
, give thelistenForMessageInConversation
object asubscribe
function.
listenForMessageInConversation: {subscribe: () => {}},
- Destructure the third positional argument,
contextValue
, for itspubsub
property.
listenForMessageInConversation: {subscribe: (_, __, { pubsub }) => {}},
- Return the results of calling
pubsub.asyncIterator
, passing in an array with the event string we're listening for:"NEW_MESSAGE_SENT"
.
listenForMessageInConversation: {subscribe: (_, __, { pubsub }) => {return pubsub.asyncIterator(["NEW_MESSAGE_SENT"])}},
At this point, you'll probably see an error from TypeScript about the type that the subscribe
function returns. This is a known bug. Currently, there are two workarounds. You can either apply // @ts-ignore
to the line just above the error, or you can modify the object returned as shown below under Option 2
. Please pick whichever option you like best!
listenForMessageInConversation: {// @ts-ignoresubscribe: (_, __, { pubsub }) => {return pubsub.asyncIterator(["NEW_MESSAGE_SENT"])}},
listenForMessageInConversation: {subscribe: (_, __, {pubsub}) => {return {[Symbol.asyncIterator]: () => pubsub.asyncIterator(["NEW_MESSAGE_SENT"])}}},
Want to learn more about the AsyncIterator
interface? Check out the MDN Web Docs.
Update the Mutation
resolver
The resolver function for Mutation.sendMessage
is publishing the right event, but it's not passing anything along with it. In order for our subscribe
function to receive the new data, our mutation needs to pass it along as its payload.
Jump to resolvers/Mutation.ts
.
- Scroll down to where we call
pubsub.publish
in theMutation.sendMessage
resolver. Currently, we pass a second argument to this call, an object.
await pubsub.publish("NEW_MESSAGE_SENT", {});
- Give the object a key that matches the name of our
Subscription
field.
await pubsub.publish("NEW_MESSAGE_SENT", {listenForMessageInConversation: // TODO});
- As the value, pass in an object containing only the attributes of the message that are present on the
Message
type. Hint: Check out the attributes returned by the call to the database. Which ones should we pass along? Do all the names match the fields onMessage
?
await pubsub.publish("NEW_MESSAGE_SENT", {listenForMessageInConversation: {id,text: messageText,sentFrom,sentTo,sentTime,},});
Try it out!
Return to Studio Explorer. Let's build some operations!
Running a subscription
We'll start by subscribing to a particular conversation. Open up the SubscribeToMessagesInConversation
operation from your Operation Collection; alternatively, copy it below.
subscription SubscribeToMessagesInConversation($listenForMessageInConversationId: ID!) {listenForMessageInConversation(id: $listenForMessageInConversationId) {textsentTime}}
And in the Variables panel:
{"listenForMessageInConversationId": "xeno-ripley-chat"}
This should kick off the subscription in the right-hand Response panel (a little window labeled Subscriptions should appear near the bottom).
Next, open up a new tab. Here, we'll trigger a mutation to send a message to that conversation (SendMessageToConversation
from your Operation Collection).
mutation SendMessageToConversation($message: NewMessageInput!) {sendMessage(message: $message) {idtextsentTo {idname}}}
And in the Variables panel:
{"message": {"text": "I hope there are no hard feelings about before!","conversationId": "xeno-ripley-chat"}}
Note: To participate in conversation "xeno-ripley-chat", you should be authenticated as either user "xeno" or "ripley". (This means that your Authorization
header should have the value Bearer xeno
or Bearer ripley
.)
Try updating your Authorization
header - and sending a response from the other participant in the conversation!
Share your questions and comments about this lesson
Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.
You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.