Skip to content

GraphQL Subscriptions

Real-time updates via WebSocket subscriptions in Orbit GraphQL.

Setup

typescript
import { Module } from '@galaxy-stack/orbit-common';
import { GraphQLModule } from '@galaxy-stack/orbit-graphql';

@Module({
  imports: [
    GraphQLModule.forRoot({
      autoSchemaFile: true,
      subscriptions: {
        'graphql-ws': true,
      },
    }),
  ],
})
export class AppModule {}

Basic Subscription

typescript
import { Resolver, Subscription } from '@galaxy-stack/orbit-graphql';
import { PubSub } from '@galaxy-stack/orbit-graphql';

const pubSub = new PubSub();

@Resolver()
export class NotificationsResolver {
  @Subscription('messageAdded', {
    resolve: (payload) => payload.messageAdded,
  })
  messageAdded() {
    return pubSub.asyncIterator('MESSAGE_ADDED');
  }
}

Publishing Events

typescript
@Injectable()
export class MessagesService {
  async createMessage(data: CreateMessageDto) {
    const message = await this.messagesRepo.create(data);
    
    pubSub.publish('MESSAGE_ADDED', { messageAdded: message });
    
    return message;
  }
}

Filtered Subscriptions

typescript
@Subscription('messageAdded', {
  filter: (payload, variables) => {
    return payload.messageAdded.channelId === variables.channelId;
  },
})
messageAdded(@Args('channelId') channelId: string) {
  return pubSub.asyncIterator('MESSAGE_ADDED');
}

With Authentication

typescript
@Subscription('privateMessage', {
  filter: (payload, variables, context) => {
    return payload.recipientId === context.user.id;
  },
})
@UseGuards(WsAuthGuard)
privateMessage(@Context() ctx: GraphQLContext) {
  return pubSub.asyncIterator('PRIVATE_MESSAGE');
}

Client Connection

typescript
import { createClient } from 'graphql-ws';

const client = createClient({
  url: 'ws://localhost:3000/graphql',
});

client.subscribe(
  {
    query: `subscription { messageAdded { id content } }`,
  },
  {
    next: (data) => console.log(data),
    error: (err) => console.error(err),
    complete: () => console.log('done'),
  },
);

Released under the MIT License.