Bird
Raised Fist0
NestJSframework~10 mins

Subscriptions in NestJS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Subscriptions
Client sends subscription request
↓
Server sets up subscription resolver
↓
Server listens for events/data changes
↓
Event occurs -> Server pushes update
↓
Client receives real-time data
↓
Client can unsubscribe anytime
↓
Subscription ends
This flow shows how a client subscribes to real-time data updates, the server listens and pushes updates, and the client receives them until unsubscribing.
Execution Sample
NestJS
import { Resolver, Subscription } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';

const pubSub = new PubSub();

@Resolver()
export class MessageResolver {
  @Subscription(() => String)
  messageSent() {
    return pubSub.asyncIterator('messageSent');
  }
}
This code sets up a GraphQL subscription in NestJS that listens for 'messageSent' events and pushes string messages to subscribed clients.
Execution Table
StepActionServer StateClient StateOutput
1Client sends subscription requestWaiting for subscriptionRequest sentNo data yet
2Server sets up subscription resolverSubscription resolver readyWaiting for dataNo data yet
3Server listens for 'messageSent' eventsListening for eventsSubscribedNo data yet
4Event 'messageSent' triggered with 'Hello!'Event receivedReceives update'Hello!' sent to client
5Client receives 'Hello!'Idle, waiting for next eventData updated: 'Hello!'Client UI updates
6Client unsubscribesSubscription closedUnsubscribedNo further updates
7No more events sentNo active subscriptionsNo active subscriptionsSubscription ended
💡 Client unsubscribes or connection closes, ending the subscription.
Variable Tracker
VariableStartAfter Step 3After Step 4After Step 6Final
subscriptionActivefalsetruetruefalsefalse
lastMessagenullnull'Hello!''Hello!''Hello!'
Key Moments - 3 Insights
Why does the client not receive any data immediately after subscribing?
Because the subscription only pushes data when an event occurs (see Step 3 and 4 in execution_table). Until then, the client waits.
What happens if the client unsubscribes but the server still emits events?
The client will not receive updates after unsubscribing (Step 6), as the subscription is closed on the server side.
How does the server know which events to send to which clients?
The server uses the subscription resolver and PubSub asyncIterator to listen for specific events and push updates only to subscribed clients (Step 2 and 3).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, at which step does the client first receive data?
AStep 2
BStep 4
CStep 5
DStep 6
💡 Hint
Check the 'Output' column for when 'Hello!' is sent to client.
According to variable_tracker, what is the value of 'subscriptionActive' after the client unsubscribes?
Afalse
Bnull
Ctrue
D'Hello!'
💡 Hint
Look at the 'After Step 6' column for 'subscriptionActive'.
If the server never triggers the 'messageSent' event, what will the client see?
AError message
BContinuous data updates
CNo data received
DSubscription ends immediately
💡 Hint
Refer to Steps 3 and 4 in execution_table where data is sent only on event.
Concept Snapshot
Subscriptions in NestJS GraphQL:
- Use @Subscription decorator in resolver
- Return pubSub.asyncIterator(eventName) to listen
- Client subscribes and waits for events
- Server pushes updates on event
- Client receives real-time data until unsubscribing
Full Transcript
Subscriptions in NestJS allow clients to receive real-time updates from the server. The client sends a subscription request, and the server sets up a subscription resolver that listens for specific events using PubSub. When an event occurs, the server pushes data to all subscribed clients. The client receives these updates and can unsubscribe anytime to stop receiving data. This flow enables live data communication, such as chat messages or notifications, in a simple and efficient way.

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

  1. Step 1: Understand the role of subscriptions

    Subscriptions are designed to push live data updates to clients without the client needing to request repeatedly.
  2. Step 2: Compare with other options

    HTTP GET requests, database migrations, and serving static files are unrelated to live data updates.
  3. Final Answer:

    To send live updates automatically to clients -> Option B
  4. 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

  1. Step 1: Identify the decorator for subscriptions

    The @Subscription decorator marks a method as a GraphQL subscription resolver in NestJS.
  2. Step 2: Differentiate from other decorators

    @Query is for queries, @Mutation for mutations, and @Injectable for services, not subscriptions.
  3. Final Answer:

    @Subscription -> Option C
  4. 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?
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!' });
medium
A. New message: Hello!
B. Hello!
C. messageAdded
D. Error: asyncIterator not found

Solution

  1. Step 1: Understand the subscription resolver

    The resolver listens to 'messageAdded' events and uses the resolve function to format the payload text.
  2. Step 2: Analyze the published payload

    The payload has { text: 'Hello!' }, so the resolve function returns 'New message: Hello!'.
  3. Final Answer:

    New message: Hello! -> Option A
  4. Quick Check:

    Resolve formats payload = 'New message: Hello!' [OK]
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

  1. Step 1: Check subscription method correctness

    The method correctly returns pubSub.asyncIterator with the event name.
  2. Step 2: Identify missing event publishing

    No call to pubSub.publish('newNotification', ...) means no events are emitted, so clients receive no updates.
  3. Final Answer:

    No events are published, so no updates sent -> Option D
  4. 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

  1. Step 1: Understand subscription filtering

    NestJS supports a filter option in the @Subscription decorator to send events selectively based on payload and context.
  2. 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.
  3. Final Answer:

    Use filter option in @Subscription to send only matching messages -> Option A
  4. Quick Check:

    Filter option = selective subscription updates [OK]
Hint: Use @Subscription filter option to send selective updates [OK]
Common Mistakes:
  • Not using filter option and sending all events
  • Trying to filter after asyncIterator returns
  • Using queries instead of subscriptions for live updates
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard