Skip to main content
Version: v3.x (DDN)

GraphQL Subscriptions

GraphQL subscriptions allow you to push real-time updates from your database to clients, making them ideal for building reactive applications without constant polling.

Subscriptions are supported for the following queries:

Example:

subscription UserNotificationSubscription {
notifications(where: { user_id: { _eq: 123 } }) {
id
created_at
message
}
}

Enabling Subscriptions

You can enable subscriptions on your GraphQL API in the following ways:

New Hasura DDN Project

If you're starting fresh, set up a Hasura DDN project using the quickstart guide. After adding your models to the supergraph using the ddn model add command, subscription capabilities are automatically generated! For further customization, you can edit the metadata.

Existing Hasura DDN Project

To enable subscriptions in an existing DDN project, use the following CLI command:

ddn codemod upgrade-graphqlconfig-subscriptions

This command updates the local metadata files, adding subscription-specific configurations. After running this, create a supergraph build and test the subscriptions on the API. For further customization, you can edit the metadata.

Metadata Configuration

You can also configure subscriptions by editing the metadata in your DDN project.

Root Type Name

Set or update the subscription root type in your GraphQL API by modifying the graphql-config.hml file located at globals/metadata/graphql-config.hml. This ensures the subscription root type is defined, which is necessary for enabling subscriptions. You will have to add the following in the definition for GraphqlConfig

subscription:
rootOperationTypeName: Subscription

Example:

<project-root>/globals/metadata/graphql-config.hml
kind: GraphqlConfig
version: v1
definition:
query:
rootOperationTypeName: Query
mutation:
rootOperationTypeName: Mutation
subscription:
rootOperationTypeName: Subscription

Model Root Field

For each model, update the root field name for subscriptions in the corresponding model's HML file. You can also configure other optional parameters, such as the polling interval, the root field's description, and its deprecation status.

An example of an Article model definition with subscriptions enabled for the selectMany, selectUniques, and aggregate root fields:

<project-root>/<subgraph-name>/metadata/Article.hml
kind: Model
version: v1
definition:
name: Article
objectType: Article
source:
dataConnectorName: my_connector
collection: article
aggregateExpression: ArticleAggExp
graphql:
selectMany:
queryRootField: article
subscription:
rootField: article
description: Subscribe to article model
selectUniques:
- queryRootField: articleById
uniqueIdentifier:
- id
subscription:
rootFIeld: articleById
description: Subscribe to article model by its unique id
deprecated:
reason: Use article root field with filters
orderByExpressionType: ArticleOrderBy
filterInputTypeName: ArticleFilterInput
aggregate:
queryRootField: articleAggregate
subscription:
rootField: articleAggregate

Polling Interval

You can set the polling interval (in milliseconds) within the model's GraphQL definition to determine how often the engine checks for updates. If not specified, the interval defaults to 1000 milliseconds (1 second).

An example of an Article model definition that has a custom polling interval configured for the selectMany subscription field:

<project-root>/<subgraph-name>/metadata/Article.hml
kind: Model
version: v1
definition:
name: Article
objectType: Article
source:
dataConnectorName: my_connector
collection: article
aggregateExpression: ArticleAggExp
graphql:
selectMany:
queryRootField: article
subscription:
rootField: article
pollingIntervalMs: 2000 # 2 seconds
orderByExpressionType: ArticleOrderBy
filterInputTypeName: ArticleFilterInput
Polling intervals and performance

Choosing the right polling interval is key to the performance and stability of your subscription API. Setting too short an interval can overburden your database with excessive queries, which can degrade performance, especially in high-traffic environments. Conversely, setting too long an interval may delay critical updates, making your real-time application less responsive.

For example, a short interval might be necessary for live sports score updates or stock trading platforms where real-time precision is critical. A longer interval could be suitable for use cases like updating daily sales reports, or sending periodic system health metrics—scenarios where updates are not urgent, and system stability is prioritized over immediate data freshness. The default setting of 1 second is chosen to accommodate most use cases, but should be adjusted based on your specific real-time needs.

Permissions

Access to subscription root fields is managed through the select permission definition. To allow a role to use subscriptions for a specific model, set allowSubscriptions to true in the model's permission definition.

Example of a select permission for an Article model with subscriptions allowed for the user role:

<project-root>/<subgraph-name>/metadata/Article.hml
kind: ModelPermissions
version: v1
definition:
modelName: Article
permissions:
- role: user
select:
filter: null
allowSubscriptions: true