diff --git a/docs/docs.json b/docs/docs.json index 199ef4f5..8241e747 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -167,11 +167,12 @@ "icon": "bridge-circle-check", "pages": [ "router/proxy-capabilities", - "router/proxy-capabilities/request-headers-operations", - "router/proxy-capabilities/response-header-operations", + "router/proxy-capabilities/subgraph-request-header-operations", + "router/proxy-capabilities/subgraph-response-header-operations", "router/proxy-capabilities/forward-client-extensions", "router/proxy-capabilities/adjusting-cache-control", - "router/proxy-capabilities/override-subgraph-config" + "router/proxy-capabilities/override-subgraph-config", + "router/proxy-capabilities/router-response-header-operations" ] }, { @@ -771,6 +772,14 @@ { "source": "/router/event-driven-federated-subscriptions-edfs/:path*", "destination": "/router/cosmo-streams/:path*" + }, + { + "source": "/router/proxy-capabilities/request-headers-operations", + "destination": "/router/proxy-capabilities/subgraph-request-header-operations" + }, + { + "source": "/router/proxy-capabilities/response-header-operations", + "destination": "/router/proxy-capabilities/subgraph-response-header-operations" } ] } diff --git a/docs/router/mcp.mdx b/docs/router/mcp.mdx index 903e988d..a372247b 100644 --- a/docs/router/mcp.mdx +++ b/docs/router/mcp.mdx @@ -233,7 +233,7 @@ storage_providers: | `router_url` | Custom URL to use for the router GraphQL endpoint in MCP responses. Use this when your router is behind a proxy. | - | | `storage.provider_id` | The ID of a storage provider to use for loading GraphQL operations. Only file_system providers are supported. | - | | `session.stateless` | Whether the MCP server should operate in stateless mode. When true, no server-side session state is maintained between requests. | `true` | -| `graph_name` | The name of the graph this router exposes via MCP. Used to build the MCP server name (wundergraph-cosmo-) and for logging; it does not select a different graph. | `mygraph` | +| `graph_name` | The name of the graph this router exposes via MCP. Used to build the MCP server name (wundergraph-cosmo-\) and for logging; it does not select a different graph. | `mygraph` | | `exclude_mutations` | Whether to exclude mutation operations from being exposed | `false` | | `enable_arbitrary_operations` | Whether to allow arbitrary GraphQL operations to be executed. Security risk: Should only be enabled in secure, internal environments. | `false` | | `expose_schema` | Whether to expose the full GraphQL schema. Security risk: Should only be enabled in secure, internal environments. | `false` | @@ -396,7 +396,7 @@ The MCP server forwards **all headers** from MCP clients to the Router, includin - Maintain consistent security and observability across all API consumers - All headers sent by MCP clients are forwarded through the complete chain: MCP Client -> MCP Server -> Router -> Subgraphs. The router's [header forwarding rules](/router/proxy-capabilities/request-headers-operations) determine what ultimately reaches your subgraphs. + All headers sent by MCP clients are forwarded through the complete chain: MCP Client -> MCP Server -> Router -> Subgraphs. The router's [header forwarding rules](/router/proxy-capabilities/subgraph-request-header-operations) determine what ultimately reaches your subgraphs. ### Common Use Cases diff --git a/docs/router/proxy-capabilities.mdx b/docs/router/proxy-capabilities.mdx index 50af0ee1..95477262 100644 --- a/docs/router/proxy-capabilities.mdx +++ b/docs/router/proxy-capabilities.mdx @@ -7,10 +7,11 @@ sidebarTitle: Overview - - + + + diff --git a/docs/router/proxy-capabilities/router-response-header-operations.mdx b/docs/router/proxy-capabilities/router-response-header-operations.mdx new file mode 100644 index 00000000..0dee5649 --- /dev/null +++ b/docs/router/proxy-capabilities/router-response-header-operations.mdx @@ -0,0 +1,43 @@ +--- +title: "Router Response Header Operations" +description: "Set custom response headers at the router level that apply to the final response sent to clients." +icon: "arrow-right-from-bracket" +--- + +## Router Response Header Setting + +The router allows you to set custom response headers that are applied to the final HTTP response sent to the client. These headers are set at the **router level**, meaning they are applied after all subgraph requests have been completed and their responses have been aggregated. + +This is different from subgraph response headers, which are processed for each individual subgraph request—router response header operations run exactly once per request, after all subgraph responses have been returned and processed, but before the final response is sent to the client. + +### Configuration Example + +You can configure router response headers in your router configuration file using expressions: + +```yaml +# config.yaml +headers: + router: + response: + - name: X-Demo-Header + expression: "request.header.Get('X-Get-Status') == 'demo' ? 'demo-value' : ''" +``` + +### How it works + +After all subgraph requests are completed and their responses aggregated, the router evaluates the expression. In this example: + +1. The router checks if the incoming request contains a header `X-Get-Status` with the value `"demo"` +2. If true, it sets the response header `X-Demo-Header` to `"demo-value"` +3. If false, the expression returns an empty string, and the header is not set (the router will not set headers with empty string values) + +This allows you to conditionally set response headers based on request context, making it useful for scenarios like feature flags, A/B testing, or environment-specific configurations. + + + Router response headers will override any response headers with the same name that were set or propagated at the subgraph level. However, if the router response header expression evaluates to an empty string (`""`), the existing response header value won't be unset—it will remain unchanged. + + + + Currently, it is not possible to access headers propagated from subgraphs within router-level expressions, or programmatically unset any headers that were propagated at the subgraph level. Router-level expressions can only access request context (like incoming request headers), not the outgoing response headers set by subgraphs. + + diff --git a/docs/router/proxy-capabilities/request-headers-operations.mdx b/docs/router/proxy-capabilities/subgraph-request-header-operations.mdx similarity index 99% rename from docs/router/proxy-capabilities/request-headers-operations.mdx rename to docs/router/proxy-capabilities/subgraph-request-header-operations.mdx index 2bb6e9c0..468d0e1b 100644 --- a/docs/router/proxy-capabilities/request-headers-operations.mdx +++ b/docs/router/proxy-capabilities/subgraph-request-header-operations.mdx @@ -1,5 +1,5 @@ --- -title: "Request Headers Operations" +title: "Subgraph Request Headers Operations" description: "The router allows users to operate on the request headers." icon: "arrow-right-to-bracket" --- diff --git a/docs/router/proxy-capabilities/response-header-operations.mdx b/docs/router/proxy-capabilities/subgraph-response-header-operations.mdx similarity index 99% rename from docs/router/proxy-capabilities/response-header-operations.mdx rename to docs/router/proxy-capabilities/subgraph-response-header-operations.mdx index e6720362..c2ad93eb 100644 --- a/docs/router/proxy-capabilities/response-header-operations.mdx +++ b/docs/router/proxy-capabilities/subgraph-response-header-operations.mdx @@ -1,5 +1,5 @@ --- -title: "Response Header Operations" +title: "Subgraph Response Header Operations" description: "Similar to request headers, we also allow for operations to be run on the headers of the router responses" icon: "arrow-right-from-bracket" --- diff --git a/docs/router/subscriptions/websocket-subprotocols.mdx b/docs/router/subscriptions/websocket-subprotocols.mdx index e760fb25..25849112 100644 --- a/docs/router/subscriptions/websocket-subprotocols.mdx +++ b/docs/router/subscriptions/websocket-subprotocols.mdx @@ -60,7 +60,7 @@ For such cases, you can configure the Router to accept clients to Authenticate u When enabled, a client can set up a WebSocket connection and then send a JWT as part of the initial WebSocket message using the `initial_payload`field. -In addition to allowing clients to authenticate using this method, you can also enable the `export_token`option. This feature takes the token from the initial payload and exports it into the Header of the Upgrade request. This allows the Router to treat every Subscription from this client as if the client sent the token as a header. Consequently, if [header forwarding](/router/proxy-capabilities/request-headers-operations) rules are enabled, the exported token will be forwarded accordingly. +In addition to allowing clients to authenticate using this method, you can also enable the `export_token`option. This feature takes the token from the initial payload and exports it into the Header of the Upgrade request. This allows the Router to treat every Subscription from this client as if the client sent the token as a header. Consequently, if [header forwarding](/router/proxy-capabilities/subgraph-request-header-operations) rules are enabled, the exported token will be forwarded accordingly. ```yaml # config.yaml