Skip to content

Commit b28881e

Browse files
authored
docs(router): Add override_labels documentation and configuration (#7163)
1 parent 33ad3e6 commit b28881e

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

packages/web/docs/src/content/router/configuration/index.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ that explains how to use that feature.
1818
- [`log`](./configuration/log): Control what the router logs and how it formats log messages.
1919
- [`override_subgraph_urls`](./configuration/override_subgraph_urls): Route requests to different
2020
subgraph URLs dynamically.
21+
- [`override_labels`](./configuration/override_labels): Dynamically activate or deactivate
22+
progressive override labels.
2123
- [`query_planner`](./configuration/query_planner): Add safety limits and debugging for query
2224
planning.
2325
- [`supergraph`](./configuration/supergraph): Tell the router where to find your supergraph schema.
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
title: 'override_labels'
3+
---
4+
5+
# override_labels
6+
7+
The `override_labels` configuration allows you to dynamically activate or deactivate progressive
8+
override labels at runtime, based on the properties of an incoming request.
9+
10+
## What is Progressive Override?
11+
12+
As a supergraph evolves, you often need to move fields from one subgraph to another. For example,
13+
imagine you are migrating the `status` of an `Order` from a general `orders` subgraph to a new, more
14+
specialized `fulfillment` subgraph.
15+
16+
The `@override` directive in Apollo Federation is used for this, but making this change for all
17+
traffic at once can be risky. Progressive override allows for a safer, incremental migration by
18+
using a `label` on the directive:
19+
20+
```graphql filename="fulfillment-subgraph.graphql"
21+
extend schema @link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@key", "@override"])
22+
23+
type Order @key(fields: "id") {
24+
id: ID!
25+
# The "use-fulfillment-service" label controls this override
26+
status: String! @override(from: "orders", label: "use-fulfillment-service")
27+
}
28+
```
29+
30+
When a label like `"use-fulfillment-service"` is "active" for a request, the router will resolve
31+
`Order.status` from the new `fulfillment` subgraph. When it's inactive, it will continue to use the
32+
original `orders` subgraph.
33+
34+
The `override_labels` configuration in the router is the mechanism that determines which labels are
35+
active for any given request.
36+
37+
## How to Use It
38+
39+
This feature allows you to implement advanced deployment patterns directly from your router
40+
configuration, without needing to repeatedly update and publish your subgraph schemas. Common use
41+
cases include:
42+
43+
- **Canary Releases:** Activate a new field implementation for a small subset of traffic first.
44+
- **A/B Testing:** Activate a feature for users in a specific group (e.g., based on a `x-user-group`
45+
header) to compare behavior.
46+
- **Internal Testing:** Activate an override only for internal users.
47+
48+
## Configuration Structure
49+
50+
The `override_labels` key is a top-level map in your `router.config.yaml`. The keys within this map
51+
are the names of the labels you wish to control, as they appear in your subgraph schemas.
52+
53+
For each label, you can specify either a static boolean or an object for dynamic expression-based
54+
evaluation.
55+
56+
```yaml
57+
override_labels:
58+
# The name of the label to control
59+
use-fulfillment-service: true
60+
activate-beta-feature:
61+
expression: # ... expression definition
62+
```
63+
64+
## Value Options
65+
66+
The value for each label key defines the condition under which the label should be considered active
67+
for a given request. It can be provided in two forms: a static boolean or an object for dynamic
68+
evaluation.
69+
70+
### Static Boolean
71+
72+
- **Type:** `boolean`
73+
74+
When a boolean is provided, the label's status is statically set for all requests. `true` means the
75+
label is always active, and `false` means it is never active. This is useful for globally enabling
76+
or disabling a feature flag.
77+
78+
```yaml
79+
override_labels:
80+
# This label will be active for every single request.
81+
use-fulfillment-service: true
82+
83+
# This label will never be active.
84+
use-legacy-inventory: false
85+
```
86+
87+
### Dynamic with `expression`
88+
89+
- **Type:** `object`
90+
91+
When an `object` is provided, it must contain a VRL `expression` that evaluates to a boolean (`true`
92+
or `false`). The expression is evaluated for each request, allowing for request-time activation
93+
decisions.
94+
95+
- `expression`: **(string, required)** A VRL expression that computes the active state of the label.
96+
97+
Within the `expression`, you have access to the following context:
98+
99+
- `.request`: The incoming HTTP request object, including its headers.
100+
101+
```yaml
102+
override_labels:
103+
# This label will be active for 5% of the traffic
104+
use-fulfillment-service:
105+
expession: 'random_float(0.0, 100.0) < 5.0'
106+
107+
activate-beta-feature:
108+
expression: '.request.headers."x-user-group" == "beta"'
109+
```
110+
111+
This configuration activates the `activate-beta-feature` label only for requests that include the
112+
header `x-user-group: beta`. The `use-fulfillment-service` label is activated for approximately 5%
113+
of all requests, enabling a canary release pattern.

0 commit comments

Comments
 (0)