📖 Scenario: You are creating a real-time chat application using NestJS and GraphQL. You want users to receive new messages instantly without refreshing the page.
🎯 Goal: Build a GraphQL subscription in NestJS that streams new chat messages to subscribed clients in real time.
📋 What You'll Learn
Create a simple message array to hold chat messages
Add a configuration variable for the subscription event name
Implement a subscription resolver using NestJS GraphQL decorators
Complete the subscription setup to broadcast new messages
💡 Why This Matters
🌍 Real World
Real-time chat apps, live notifications, and instant updates use subscriptions to push data to clients without refreshing.
💼 Career
Understanding subscriptions in NestJS is key for backend developers building interactive, real-time web applications.
Progress0 / 4 steps
1
Create the initial message data array
Create a constant array called messages with these exact objects: { id: 1, text: 'Hello' } and { id: 2, text: 'Welcome' }.
NestJS
Hint
Use const messages = [ ... ] with two objects inside the array.
2
Add a subscription event name constant
Add a constant string called NEW_MESSAGE_EVENT and set it to 'newMessage'.
NestJS
Hint
Use const NEW_MESSAGE_EVENT = 'newMessage'; to define the event name.
3
Implement the subscription resolver method
Inside a NestJS resolver class, create a method called newMessage decorated with @Subscription(() => Message) that returns an async iterator from pubSub.asyncIterator(NEW_MESSAGE_EVENT). Use pubSub as the PubSub instance.
NestJS
Hint
Use @Subscription(() => Message) above the newMessage method and return pubSub.asyncIterator(NEW_MESSAGE_EVENT).
4
Complete the subscription by publishing new messages
Add a method called sendMessage that takes a text string, creates a new message object with an id one higher than the last message, pushes it to messages, and calls pubSub.publish(NEW_MESSAGE_EVENT, { newMessage: newMsg }).
NestJS
Hint
Create sendMessage that adds a new message and publishes it with pubSub.publish.
Practice
(1/5)
1. What is the main purpose of subscriptions in NestJS GraphQL?
easy
A. To perform database migrations
B. To send live updates automatically to clients
C. To handle HTTP GET requests
D. To serve static files
Solution
Step 1: Understand the role of subscriptions
Subscriptions are designed to push live data updates to clients without the client needing to request repeatedly.
Step 2: Compare with other options
HTTP GET requests, database migrations, and serving static files are unrelated to live data updates.
Final Answer:
To send live updates automatically to clients -> Option B
Quick Check:
Subscriptions = live updates [OK]
Hint: Subscriptions push live data updates automatically [OK]
Common Mistakes:
Confusing subscriptions with HTTP request handling
Thinking subscriptions manage database tasks
Assuming subscriptions serve static content
2. Which decorator is used in NestJS to define a GraphQL subscription method?
easy
A. @Query
B. @Mutation
C. @Subscription
D. @Injectable
Solution
Step 1: Identify the decorator for subscriptions
The @Subscription decorator marks a method as a GraphQL subscription resolver in NestJS.
Step 2: Differentiate from other decorators
@Query is for queries, @Mutation for mutations, and @Injectable for services, not subscriptions.
Final Answer:
@Subscription -> Option C
Quick Check:
@Subscription decorator = subscriptions [OK]
Hint: Use @Subscription decorator for live data methods [OK]
Common Mistakes:
Using @Query or @Mutation instead of @Subscription
Confusing @Injectable with subscription decorators
Omitting the decorator entirely
3. Given this subscription resolver snippet, what will be the output when a new message is published?
Hint: Resolve function formats payload text in subscription [OK]
Common Mistakes:
Expecting raw payload without resolve formatting
Confusing event name with output
Assuming asyncIterator causes error
4. Identify the error in this subscription setup:
import { Resolver, Subscription } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';
const pubSub = new PubSub();
@Resolver()
export class NotificationResolver {
@Subscription(() => String)
newNotification() {
return pubSub.asyncIterator('newNotification');
}
}
// Missing pubSub.publish call elsewhere
medium
A. pubSub.asyncIterator called with wrong event name
B. Subscription method missing return statement
C. Incorrect decorator used for subscription
D. No events are published, so no updates sent
Solution
Step 1: Check subscription method correctness
The method correctly returns pubSub.asyncIterator with the event name.
Step 2: Identify missing event publishing
No call to pubSub.publish('newNotification', ...) means no events are emitted, so clients receive no updates.
Final Answer:
No events are published, so no updates sent -> Option D
Quick Check:
Missing publish call = no updates sent [OK]
Hint: Always publish events to trigger subscription updates [OK]
Common Mistakes:
Forgetting to call pubSub.publish
Using wrong event name in asyncIterator
Omitting return in subscription method
5. You want to create a subscription that only sends updates to clients when the message's author matches their user ID. Which approach correctly implements this filter in NestJS subscriptions?
A) Use pubSub.asyncIterator('messageAdded') directly without filtering.
B) Use the filter option in the @Subscription decorator to compare payload author and user ID.
C) Filter messages inside the resolver method after returning the async iterator.
D) Use a separate query instead of subscription to filter messages.
hard
A. Use filter option in @Subscription to send only matching messages
B. Subscribe directly without filtering; client filters messages
C. Filter messages inside resolver after asyncIterator returns
D. Use query instead of subscription for filtering
Solution
Step 1: Understand subscription filtering
NestJS supports a filter option in the @Subscription decorator to send events selectively based on payload and context.
Step 2: Evaluate options
The filter option in the @Subscription decorator compares the message author with the client's user ID from context, sending only relevant updates. Subscribing directly without filtering sends all events to clients, filtering after the asyncIterator returns is not the standard approach, and using a query provides no live updates.
Final Answer:
Use filter option in @Subscription to send only matching messages -> Option A