Skip to content

fix(@nestjs/apollo): expose schema transform hook on gateway driver#3969

Merged
kamilmysliwiec merged 1 commit into
nestjs:masterfrom
maruthang:fix/issue-3296-apollo-gateway-transform-schema
May 1, 2026
Merged

fix(@nestjs/apollo): expose schema transform hook on gateway driver#3969
kamilmysliwiec merged 1 commit into
nestjs:masterfrom
maruthang:fix/issue-3296-apollo-gateway-transform-schema

Conversation

@maruthang

Copy link
Copy Markdown
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Other... Please describe:

What is the current behavior?

Issue Number: #3296

User-supplied schema transforms are silently dropped when using ApolloGatewayDriver.

  • Placing transformSchema on the gateway option does nothing — those options are forwarded verbatim to new ApolloGateway(), which silently ignores fields it does not recognize.
  • Placing transformSchema on the server option is explicitly disallowed — the type definition Omits transformSchema from the gateway server config.

The result is that there is no supported way to apply custom directives or otherwise transform the composed supergraph schema in a federated setup. Apollo Server consumes the gateway schema via the synchronous gateway.onSchemaLoadOrUpdate event fired during gateway.load(), so any transform has to be in place before that event reaches the server — which the current driver never does.

What is the new behavior?

Adds an optional transformSchema callback at the top level of ApolloGatewayDriverConfig (sibling of gateway and server):

transformSchema?: (schema: GraphQLSchema) => GraphQLSchema | Promise<GraphQLSchema>;

When provided, the driver wraps the underlying ApolloGateway with a small adapter that:

  1. Queues Apollo Server's onSchemaLoadOrUpdate listener instead of registering it directly on the real gateway.
  2. Awaits the user's transformSchema during gateway.load().
  3. Emits the transformed schema to the queued listener before load() returns, so Apollo Server only ever sees the transformed version.

When transformSchema is omitted, the gateway is passed through unchanged — zero behavioral cost for existing users.

Documented limitation: post-startup gateway updates (e.g. supergraph polling) are forwarded untransformed; the JSDoc on the new option calls this out. The primary use case (registering custom directives at startup) is fully covered.

Tests: new e2e spec packages/apollo/tests/e2e/graphql-gateway-transform-schema.spec.ts covers two cases:

  • transformSchema is invoked exactly once during gateway startup.
  • An identity transformSchema still serves federated queries correctly.

Does this PR introduce a breaking change?

  • Yes
  • No

Additive, optional field with a backward-compatible default. Existing configurations behave identically.

Other information

Files touched:

  • packages/apollo/lib/interfaces/apollo-gateway-driver-config.interface.ts — new optional transformSchema field on the driver config.
  • packages/apollo/lib/drivers/apollo-gateway.driver.ts — wraps the gateway with the transform adapter when the option is provided; passes through otherwise.
  • packages/apollo/tests/e2e/graphql-gateway-transform-schema.spec.ts — regression coverage.

Closes #3296

ApolloGatewayDriverConfig had no entry point for transforming the
composed supergraph schema. Options placed on `gateway` were forwarded
verbatim to `new ApolloGateway()`, which silently ignores fields it
does not recognize, while `server` explicitly omits `transformSchema`.
Apollo Server consumes the gateway schema via the synchronous
`onSchemaLoadOrUpdate` event fired during `gateway.load()`, so the
transform must be applied before that event reaches the server.

Add an optional `transformSchema` callback at the gateway driver
config level. When provided, the driver wraps the gateway with a
small adapter that queues Apollo Server's listener, awaits the user
transform during `load()`, and emits the transformed schema before
returning. When omitted, the gateway is passed through unchanged.

Closes nestjs#3296
@kamilmysliwiec kamilmysliwiec merged commit e98b7d8 into nestjs:master May 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inability to Use transformSchema and Custom Directives in Apollo Gateway Configuration with @nestjs/graphql

2 participants