Subscriptions let your app send real-time updates to users. They keep users informed without needing to refresh the page.
Subscriptions in NestJS
import { Resolver, Subscription } from '@nestjs/graphql'; import { PubSub } from 'graphql-subscriptions'; const pubSub = new PubSub(); @Resolver() export class MyResolver { @Subscription(() => String, { resolve: (payload) => payload, }) messageSent() { return pubSub.asyncIterator('messageSent'); } }
Use @Subscription decorator to mark a method as a subscription.
PubSub helps send and listen to events for subscriptions.
import { Resolver, Subscription } from '@nestjs/graphql'; import { PubSub } from 'graphql-subscriptions'; const pubSub = new PubSub(); @Resolver() export class ChatResolver { @Subscription(() => String) newMessage() { return pubSub.asyncIterator('newMessage'); } }
userId receives them.import { Resolver, Subscription } from '@nestjs/graphql'; import { PubSub } from 'graphql-subscriptions'; const pubSub = new PubSub(); @Resolver() export class NotificationResolver { @Subscription(() => String, { filter: (payload, variables) => payload.userId === variables.userId, }) userNotification(userId: string) { return pubSub.asyncIterator('userNotification'); } }
This resolver stores messages and allows clients to send new messages via mutation. When a message is sent, it publishes an event. The subscription listens for these events and sends new messages to subscribers in real-time.
import { Resolver, Subscription, Query, Mutation, Args } from '@nestjs/graphql'; import { PubSub } from 'graphql-subscriptions'; const pubSub = new PubSub(); @Resolver() export class MessageResolver { private messages: string[] = []; @Query(() => [String]) getMessages() { return this.messages; } @Mutation(() => Boolean) sendMessage(@Args('message') message: string) { this.messages.push(message); pubSub.publish('messageSent', message); return true; } @Subscription(() => String) messageSent() { return pubSub.asyncIterator('messageSent'); } }
Subscriptions require a WebSocket connection to work properly.
Use PubSub or other event systems to manage events.
Remember to handle cleanup to avoid memory leaks in long-running subscriptions.
Subscriptions let your app send live updates to users.
Use @Subscription decorator and PubSub to create subscriptions.
They are great for chat, notifications, and live data feeds.
Practice
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 BQuick Check:
Subscriptions = live updates [OK]
- Confusing subscriptions with HTTP request handling
- Thinking subscriptions manage database tasks
- Assuming subscriptions serve static content
Solution
Step 1: Identify the decorator for subscriptions
The@Subscriptiondecorator marks a method as a GraphQL subscription resolver in NestJS.Step 2: Differentiate from other decorators
@Queryis for queries,@Mutationfor mutations, and@Injectablefor services, not subscriptions.Final Answer:
@Subscription -> Option CQuick Check:
@Subscription decorator = subscriptions [OK]
- Using @Query or @Mutation instead of @Subscription
- Confusing @Injectable with subscription decorators
- Omitting the decorator entirely
import { Resolver, Subscription } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';
const pubSub = new PubSub();
@Resolver()
export class ChatResolver {
@Subscription(() => String, {
resolve: (payload) => `New message: ${payload.text}`,
})
messageAdded() {
return pubSub.asyncIterator('messageAdded');
}
}
// Somewhere else: pubSub.publish('messageAdded', { text: 'Hello!' });Solution
Step 1: Understand the subscription resolver
The resolver listens to 'messageAdded' events and uses the resolve function to format the payload text.Step 2: Analyze the published payload
The payload has { text: 'Hello!' }, so the resolve function returns 'New message: Hello!'.Final Answer:
New message: Hello! -> Option AQuick Check:
Resolve formats payload = 'New message: Hello!' [OK]
- Expecting raw payload without resolve formatting
- Confusing event name with output
- Assuming asyncIterator causes error
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 elsewhereSolution
Step 1: Check subscription method correctness
The method correctly returns pubSub.asyncIterator with the event name.Step 2: Identify missing event publishing
No call topubSub.publish('newNotification', ...)means no events are emitted, so clients receive no updates.Final Answer:
No events are published, so no updates sent -> Option DQuick Check:
Missing publish call = no updates sent [OK]
- Forgetting to call pubSub.publish
- Using wrong event name in asyncIterator
- Omitting return in subscription method
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.Solution
Step 1: Understand subscription filtering
NestJS supports afilteroption in the@Subscriptiondecorator to send events selectively based on payload and context.Step 2: Evaluate options
Thefilteroption in the@Subscriptiondecorator 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 AQuick Check:
Filter option = selective subscription updates [OK]
- Not using filter option and sending all events
- Trying to filter after asyncIterator returns
- Using queries instead of subscriptions for live updates
Ready to prove it?
Pass the test and this pattern moves unknown
