You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

NestJS全局PubSub实例与依赖注入问题咨询

Hey there! Let's sort out how to properly set up a reusable, global PubSub provider in NestJS so you can avoid those dependency resolution errors and skip the messy circular imports.

The Best Approach: Create a Dedicated PubSub Module

Instead of cramming the PubSub provider directly into AppModule (which can lead to circular dependencies as your app grows), creating a standalone PubSubModule is the cleanest solution. It keeps your code decoupled and makes the provider available globally without forcing cross-module imports.

Here's how to build it:

  1. Create the PubSub module file (src/pubsub/pubsub.module.ts):
import { Module, Global } from '@nestjs/common';
import { PubSub } from 'graphql-subscriptions';

@Global() // This makes the module's providers available everywhere in the app
@Module({
  providers: [
    {
      provide: 'PUB_SUB',
      useValue: new PubSub(),
    },
  ],
  exports: ['PUB_SUB'], // Export the provider so other modules can inject it
})
export class PubSubModule {}
  1. Import the PubSubModule into your AppModule
    Now you just need to add this module to your root AppModule once, and it will be available across all other modules automatically:
import { Module } from '@nestjs/common';
import { PubSubModule } from './pubsub/pubsub.module';
// Import your other modules (e.g., PostsModule, UsersModule)

@Module({
  imports: [PubSubModule, PostsModule, UsersModule],
})
export class AppModule {}

Injecting PubSub in Other Modules/Resolvers

Once the global module is set up, you can inject the PubSub instance anywhere in your app using the @Inject() decorator. For example, in a resolver:

import { Resolver, Subscription, Query, Args, Inject } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';
import { Post } from './models/post.model';

@Resolver(() => Post)
export class PostsResolver {
  constructor(@Inject('PUB_SUB') private readonly pubSub: PubSub) {}

  // Example subscription
  @Subscription(() => Post)
  postCreated() {
    return this.pubSub.asyncIterator('postCreated');
  }

  // Example mutation that triggers the subscription
  @Mutation(() => Post)
  createPost(@Args('input') input: CreatePostInput) {
    const newPost = // Add your post creation logic here
    this.pubSub.publish('postCreated', { postCreated: newPost });
    return newPost;
  }
}

Fixing Dependency Resolution Errors

If you're still hitting errors, check these common issues:

  • You forgot to mark the PubSubModule as @Global(), so other modules can't access the provider without explicitly importing it.
  • You're missing the @Inject('PUB_SUB') decorator in the constructor (Nest can't guess which provider you want otherwise).
  • You accidentally imported AppModule into another module, creating a circular dependency—with the global PubSubModule, you never need to do this.

Why This Works

By creating a dedicated global module, you're centralizing the PubSub instance (so it's reused everywhere) and avoiding circular dependencies because other modules don't need to import AppModule to access it. It's the recommended pattern in NestJS for shared utilities like PubSub, config services, or database connections.

内容的提问来源于stack exchange,提问作者baku

火山引擎 最新活动