|
| 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