Forward GraphQL Client Extensions | Cosmo by WunderGraph - WunderGraph
GraphQL Extensions Forwarding - Queries, Mutations, and Subscriptions
Use the extensions field to send extra data from clients to subgraphs without stuffing it into headers.
The problem
Structured context should not live in headers
Headers flatten everything. Subscriptions cannot vary headers per operation. The GraphQL spec already has a place for extra JSON: use it.
Headers are a poor fit for structured data
HTTP headers are flat strings. Sending {"features":{"newCheckout":true,"betaSearch":false}} through a header means encoding JSON as a string and decoding it everywhere it lands.
WebSocket subscriptions have no per-operation headers
A WebSocket connection is established once. After that, every subscription operation flows over the same socket. There is no way to attach a different Authorization header to operation #2 vs. operation #1.
Custom workarounds fragment the API
Teams invent sidecar endpoints, bespoke envelope formats, or hidden query arguments to work around the header limitation. None of that is standard.
Our solution
Pass any JSON context from clients to subgraphs, including subscriptions
The GraphQL extensions object is the spec-backed place for structured client context. Cosmo Router forwards it to subgraphs by default—queries, mutations, and subscriptions—without a feature flag or a custom side channel.
What happens at request time
- The router attaches the client's
extensionsobject to each outgoing subgraph request, so structured payloads stay JSON-shaped end to end for queries, mutations, and subscriptions. - GraphQL over HTTP defines
extensionsas a JSON object next toqueryandvariables. Clients put whatever structured data they need there, and the router forwards it untouched to every subgraph involved in the operation. - For
graphql-wssubscriptions,extensionslives in the subscription message payload—the reliable way to attach per-operation data on a shared WebSocket. No configuration; it works by default. - Subgraphs read the fields they care about; the router does not reshape or flatten the JSON.
Behavior
Technical behavior
- Forwarding is automatic for queries and mutations over HTTP.
- For subscriptions, requires a
graphql-wscompatible setup on both router and subgraph. - The JSON structure is preserved exactly; the router does not reshape or flatten it.
- Subgraphs must be designed to read and act on the fields they expect. The router does not validate the contents.
- No configuration required, enabled by default.
Use cases
Patterns teams use first
Auth tokens, feature flags, and client metadata: same field, different payloads.
Standards compliant
Implements the extensions field as defined in the GraphQL over HTTP specification. Works with any GraphQL client library that supports it.
Subscription support
The reliable way to send per-subscription initialization data. WebSocket connections are established once; extensions in the subscription payload carries per-operation tokens after that.
Flexible data structure
Send any JSON object (auth tokens, feature flags, client metadata) without encoding it into a flat header string.
How extensions forwarding works
Client sends extensions
Structured context lives in the JSON body under the extensions field—not squeezed into header strings—including graphql-ws subscription payloads.
Router receives the payload
The extensions field is preserved as received.
Extensions travel downstream
Extensions travel with every subgraph call on outgoing requests.
Subgraphs consume what they need
Each subgraph reads the fields it cares about and ignores the rest.