Skip to Content
SchemaSubscriptions

Subscriptions

Define Subscription fields using the @gqlkit-ts/runtime API.

Prerequisites: This guide assumes you have completed the basic setup.

Setup

Export defineSubscription from your gqlkit.ts:

import { createGqlkitApis } from "@gqlkit-ts/runtime"; import type { Context } from "./context"; export const { defineQuery, defineMutation, defineSubscription } = createGqlkitApis<Context>();

Subscription Resolvers

Use defineSubscription to define Subscription fields. The resolver is typically an async generator function:

import { defineSubscription } from "../gqlkit"; import type { Message } from "./message"; // Subscription.messageAdded(channelId: String!) export const messageAdded = defineSubscription< { channelId: string }, Message >(async function* (_root, args, ctx) { yield* ctx.pubsub.subscribe<Message>("MESSAGE_ADDED", args.channelId); });

Generates:

type Subscription { messageAdded(channelId: String!): Message! }

The same export name conventions apply as with Queries & Mutations:

// GraphQL field name: messageAdded export const Subscription$messageAdded = defineSubscription< { channelId: string }, Message >(async function* (_root, args, ctx) { yield* ctx.pubsub.subscribe<Message>("MESSAGE_ADDED", args.channelId); });

NoArgs Subscriptions

For subscriptions without arguments, use NoArgs as the first type parameter — same as with defineQuery and defineMutation. See Queries & Mutations for details.

Resolver Function Signature

Subscription resolvers receive the same four arguments as Query/Mutation resolvers, but return an AsyncIterable instead of a direct value:

(root, args, ctx, info) => AsyncIterable<T> | Promise<AsyncIterable<T>>
ArgumentDescription
rootThe root value (always undefined)
argsThe arguments passed to the field
ctxThe context object (typed via createGqlkitApis<Context>())
infoGraphQL resolve info

Inline Object Arguments

Subscription arguments support the same inline object types as queries and mutations:

export const orderUpdated = defineSubscription< { filter: { orderId: string | null; status: string | null; }; }, Order >(async function* (_root, args, ctx) { yield* ctx.pubsub.subscribe<Order>("ORDER_UPDATED", args.filter); });

Generates:

type Subscription { orderUpdated(filter: OrderUpdatedFilterInput!): Order! } input OrderUpdatedFilterInput { orderId: String status: String }

Attaching Directives

Add a third type parameter to attach directives:

import { defineSubscription } from "../gqlkit"; import type { AuthDirective } from "./directives"; import type { Message } from "./message"; export const messageAdded = defineSubscription< { channelId: string }, Message, [AuthDirective<{ role: ["USER"] }>] >(async function* (_root, args, ctx) { yield* ctx.pubsub.subscribe<Message>("MESSAGE_ADDED", args.channelId); });

Generates:

type Subscription { messageAdded(channelId: String!): Message! @auth(role: [USER]) }

See Directives for more details on defining and using custom directives.

Documentation

TSDoc comments on subscription exports are extracted as GraphQL descriptions:

/** Subscribe to new messages in a channel. */ export const messageAdded = defineSubscription< { channelId: string }, Message >(async function* (_root, args, ctx) { yield* ctx.pubsub.subscribe<Message>("MESSAGE_ADDED", args.channelId); }); /** * @deprecated Use messageAdded instead. */ export const onMessage = defineSubscription< { channelId: string }, Message >(async function* (_root, args, ctx) { yield* ctx.pubsub.subscribe<Message>("MESSAGE_ADDED", args.channelId); });

Generates:

type Subscription { """Subscribe to new messages in a channel.""" messageAdded(channelId: String!): Message! onMessage(channelId: String!): Message! @deprecated(reason: "Use messageAdded instead.") }

See Documentation for more details.

Last updated on