Skip to content

Add entity-scoped GraphQL subscription support#3548

Open
Copilot wants to merge 14 commits into
mainfrom
copilot/enhance-graphql-subscription-support
Open

Add entity-scoped GraphQL subscription support#3548
Copilot wants to merge 14 commits into
mainfrom
copilot/enhance-graphql-subscription-support

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 13, 2026

Why make this change?

  • DAB needs entity-scoped GraphQL subscriptions for created, updated, and deleted events over the existing GraphQL endpoint. Subscriptions should stay invisible unless an entity configures subscription events, use process-local Hot Chocolate WebSockets, and publish only DAB-originated writes.

What is this change?

  • Entity configuration + CLI

    • Adds entity-level entities.<name>.graphql.subscription.enabled and entities.<name>.graphql.subscription.events.
    • Supports config merge behavior through existing JSON merge/deserialization paths.
    • Updates schema validation for entity subscription config, including stored-procedure rejection and JSON schema defaults for empty event lists.
    • Adds CLI support for dab update <entity> --graphql.subscription.events and --graphql.subscription.enabled, with validation errors for invalid values.
  • GraphQL schema

    • Adds SubscriptionEvent and entity event types only when entity events are configured and eligible.
    • Generates event fields such as actorCreated, actorUpdated, actorDeleted.
    • Omits fields when no role has the matching write permission.
    • Omits Cosmos subscription fields until Cosmos write-event publishing support exists.
    • Uses the SubscriptionEvent interface as the explicit resolver marker for generated event payloads.
    • Keeps subscription schema generation compatible with the latest main Hot Chocolate 16 stable updates.
    • Resolves subscription metadata scalar fields through the normal leaf resolver so UUID and DateTime payload fields use the expected Hot Chocolate runtime types.
  • Runtime publishing

    • Keeps subscription schema fields absent unless an entity enables eligible events, while registering process-local subscription infrastructure so late-configured and hot-reloaded subscription settings can become active.
    • Enables WebSocket middleware for late configuration, while dynamically rejecting WebSocket upgrades when no eligible subscription field exists.
    • Publishes SQL DAB write events from GraphQL, REST, and MCP mutation paths.
    • Handles compound GraphQL mutations and multiple-create results by emitting one event per affected record.
    • Delete payloads publish primary-key data only, ignore non-key GraphQL arguments, and do not publish for no-op deletes.
    • Logs publish failures without converting already-committed writes into API errors.
  • Telemetry

    • Logs subscription creation, closure, WebSocket connection lifecycle, and event publication details.
    • Adds active subscription metric: active_graphql_subscriptions.
    • Increments active subscription counts only after successful subscription setup.
    • Includes eventId in payloads and publish telemetry.
    • Avoids logging full GraphQL documents, connection init payloads, authorization tokens, or record payload values.
"entities": {
  "Actor": {
    "graphql": {
      "subscription": {
        "events": [ "created", "updated", "deleted" ]
      }
    }
  }
}

How was this tested?

  • Integration Tests
  • Unit Tests
  • Solution Build
  • CodeQL Security Scan final rerun
  • Code Review Validation
  • Independent GPT-5.5 spec/code review

Final CodeQL validation was attempted after the latest spec-follow-up changes, but the validation tool hit its time limit before completing.

Sample Request(s)

subscription {
  actorUpdated {
    eventId
    utcDateTime
    actorRole
    record {
      Id
      Name
    }
  }
}
dab update Actor --graphql.subscription.events "created,updated,deleted"
dab update Actor --graphql.subscription.enabled false

Copilot AI linked an issue May 13, 2026 that may be closed by this pull request
Copilot AI and others added 4 commits May 13, 2026 22:44
Agent-Logs-Url: https://github.com/Azure/data-api-builder/sessions/be163e20-1dae-4692-a489-fb69ebe6e927

Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Azure/data-api-builder/sessions/be163e20-1dae-4692-a489-fb69ebe6e927

Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Copilot AI changed the title [WIP] Enhance GraphQL subscription support Add GraphQL subscription support May 13, 2026
Copilot AI requested a review from JerryNixon May 13, 2026 23:02
@JerryNixon JerryNixon marked this pull request as ready for review May 13, 2026 23:22
Copilot AI review requested due to automatic review settings May 13, 2026 23:22
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds entity-scoped GraphQL subscription support to DAB (schema generation + in-process Hot Chocolate WebSocket subscriptions) and publishes DAB-originated write events from GraphQL/REST paths, with config/CLI/schema updates and unit tests.

Changes:

  • Introduces per-entity GraphQL subscription configuration (graphql.subscription.enabled / graphql.subscription.events) across config object model, CLI, and JSON schema validation.
  • Generates GraphQL Subscription fields and event payload types conditionally (based on configured events + role write permissions).
  • Publishes created/updated/deleted events from mutation paths and tracks active subscriptions via metrics/telemetry.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/Service/Startup.cs Registers subscription publisher, enables Hot Chocolate in-memory subscriptions, and enables WebSockets middleware.
src/Service/Azure.DataApiBuilder.Service.csproj Adds HotChocolate in-memory subscriptions package reference.
src/Service.Tests/UnitTests/SerializationDeserializationTests.cs Adds config merge/deserialization coverage for entity subscription options.
src/Service.Tests/UnitTests/GraphQLSubscriptionEventTests.cs Adds unit tests for extracting per-record publish payloads from mutation results.
src/Service.Tests/GraphQLBuilder/SubscriptionBuilderTests.cs Adds tests for subscription SDL generation and permission-based field omission.
src/Service.GraphQLBuilder/Subscriptions/SubscriptionBuilder.cs Implements subscription SDL generation (event interface, event types, subscription fields).
src/Directory.Packages.props Central package version for HotChocolate.Subscriptions.InMemory.
src/Core/Telemetry/TelemetryMetricsHelper.cs Adds an active GraphQL subscriptions UpDownCounter metric.
src/Core/Services/ResolverTypeInterceptor.cs Wires subscription resolvers and adds special pure-resolver handling for event payload types.
src/Core/Services/GraphQLSubscriptionEventPublisher.cs Adds event publish/subscribe abstraction using Hot Chocolate topics + telemetry/logging.
src/Core/Services/GraphQLSchemaCreator.cs Adds subscription document generation and injects publisher/logger into ExecutionHelper.
src/Core/Services/ExecutionHelper.cs Adds subscription subscribe resolver, event payload resolvers, and subscription metric tracking.
src/Core/Resolvers/SqlMutationEngine.cs Publishes subscription events after successful mutations (GraphQL + REST paths).
src/Core/Resolvers/Factories/MutationEngineFactory.cs Injects subscription publisher into mutation engines.
src/Core/Configurations/RuntimeConfigValidator.cs Warns when subscriptions are enabled but no events are configured.
src/Core/Azure.DataApiBuilder.Core.csproj Adds HotChocolate in-memory subscriptions package reference.
src/Config/ObjectModel/GraphQLSubscriptionEvent.cs Adds enum for supported subscription event kinds.
src/Config/ObjectModel/EntityGraphQLSubscriptionOptions.cs Adds per-entity subscription options model.
src/Config/ObjectModel/EntityGraphQLOptions.cs Extends entity GraphQL options to include subscription settings.
src/Config/Converters/EntityGraphQLOptionsConverterFactory.cs Adds (de)serialization support for graphql.subscription in entity config.
src/Cli/ConfigGenerator.cs Adds CLI update support for entity subscription options.
src/Cli/Commands/EntityOptions.cs Adds CLI flags for graphql.subscription.enabled and graphql.subscription.events.
schemas/dab.draft.schema.json Adds JSON schema validation for entity GraphQL subscription configuration.

Comment thread src/Config/ObjectModel/EntityGraphQLSubscriptionOptions.cs Outdated
Comment thread src/Core/Services/ExecutionHelper.cs Outdated
Comment thread src/Core/Resolvers/SqlMutationEngine.cs
Comment thread src/Cli/ConfigGenerator.cs Outdated
Comment thread src/Core/Services/ResolverTypeInterceptor.cs Outdated
Comment thread src/Service/Startup.cs Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@JerryNixon
Copy link
Copy Markdown
Contributor

@copilot apply changes based on the comments in this thread

Agent-Logs-Url: https://github.com/Azure/data-api-builder/sessions/ca962dbd-4262-4080-8156-fa0941606d49

Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 14, 2026

@copilot apply changes based on the comments in this thread

The review thread feedback has been applied across ca6621d, c4df06b, and c309f8f, covering subscription/WebSocket gating, active metric ordering, key-only delete payloads, CLI validation, and explicit SubscriptionEvent resolver binding.

@JerryNixon JerryNixon requested a review from Copilot May 18, 2026 14:38
@JerryNixon
Copy link
Copy Markdown
Contributor

@copilot merge from main so this branch is up to date and review the implementation against #3547 and if it has drifted, adjust the PR so it is faithful to the spec.

…ql-subscription-support

# Conflicts:
#	src/Core/Services/GraphQLSchemaCreator.cs
#	src/Directory.Packages.props

Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Azure/data-api-builder/sessions/834d9860-e4c6-40a1-ade7-036da2ec3aa8

Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated 4 comments.

Comment thread src/Core/Services/ResolverTypeInterceptor.cs Outdated
Comment thread src/Service/Startup.cs Outdated
Comment thread src/Service/Startup.cs Outdated
Comment thread src/Core/Telemetry/TelemetryMetricsHelper.cs Outdated
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 18, 2026

@copilot merge from main so this branch is up to date and review the implementation against #3547 and if it has drifted, adjust the PR so it is ...

Merged latest origin/main in 64e95f4 and fixed the HC 16 stable merge drift in d9ce278. I reviewed the implementation against #3547; it remains aligned with the spec for entity-scoped config gating, generated subscription schema, DAB-originated write events, key-only delete payloads, telemetry, and no distributed pub/sub support.

@JerryNixon
Copy link
Copy Markdown
Contributor

@copilot apply changes based on the comments in this thread and then re-check the spec #3547 and ensure it is followed completely.

Agent-Logs-Url: https://github.com/Azure/data-api-builder/sessions/8e0156c0-e054-43a8-9618-7fb46c5fcbf1

Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 19, 2026

@copilot apply changes based on the comments in this thread and then re-check the spec https://github.com/Azure/data...

Applied the review-thread changes in 08fcdf7. Subscription event metadata fields now use the normal leaf resolver for scalar conversion, late-config/hot-reload scenarios use the real in-memory publisher and WebSocket middleware, and the active subscription metric name is aligned with existing metrics. I also re-checked #3547 after the changes and the implementation remains faithful to the spec.

@JerryNixon
Copy link
Copy Markdown
Contributor

@copilot Merge the latest changes from main into this branch.

Copilot AI and others added 2 commits May 19, 2026 16:50
…ql-subscription-support

Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Agent-Logs-Url: https://github.com/Azure/data-api-builder/sessions/f26556e6-8663-437f-98c7-e84ee2ef9b76

Co-authored-by: JerryNixon <1749983+JerryNixon@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 19, 2026

@copilot Merge the latest changes from main into this branch.

Merged latest main in fc42130 and then completed a pedantic #3547 spec follow-up in 20bf2fe. The follow-up tightens WebSocket gating, telemetry, stored-procedure/Cosmos eligibility, schema defaults, and SQL publish semantics; build and targeted tests passed.

Copilot AI requested a review from JerryNixon May 19, 2026 17:18
@Aniruddh25 Aniruddh25 modified the milestones: May 2026, June 2026 May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

[Enh]: GraphQL subscription support

4 participants