diff --git a/docs/docs.json b/docs/docs.json index 2abfffc7..bc937b7c 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -252,6 +252,7 @@ }, "router/compliance-and-data-management", "router/query-batching", + "router/feature-flags", "router/subgraph-error-propagation", "router/file-upload", "router/access-logs", diff --git a/docs/router/configuration.mdx b/docs/router/configuration.mdx index 927becd6..3ad6ee95 100644 --- a/docs/router/configuration.mdx +++ b/docs/router/configuration.mdx @@ -1855,6 +1855,35 @@ For mor information on how to use the expression language, please refer to the [ | RATE_LIMIT_SIMPLE_PERIOD | period | | The rate limiting period, e.g. "10s", "1m", etc... | 1s | | RATE_LIMIT_SIMPLE_REJECT_EXCEEDING_REQUESTS | reject_exceeding_requests | | Reject the complete request if a sub-request exceeds the rate limit. If set to false, partial responses are possible. | false | | RATE_LIMIT_SIMPLE_HIDE_STATS_FROM_RESPONSE_EXTENSION | hide_stats_from_response_extension | | Hide the rate limit stats from the response extension. If the value is true, the rate limit stats are not included in the response extension. | false | +| | overrides | | Optional per-key overrides for rate, burst, and period. Keys must match the fully qualified Redis key (prefix + suffix). | | + +### Rate Limit Overrides + +Overrides let you provide bespoke limits for specific rate-limit keys—for example, to give paying customers higher throughput or to throttle noisy tenants. Each entry in `simple_strategy.overrides` is a map keyed by the full Redis key and can override `rate`, `burst`, and `period`. + +Key structure reminder: + +- `storage.key_prefix` defines the prefix applied to every key. +- `key_suffix_expression` appends the dynamic portion at runtime. +- An override must include both segments (for example, `cosmo_rate_limit:id_premium_user`). + +The example below uses `request.auth.claims.client_id` to build suffixes such as `id_paying_client`, which then match the override keys. + +```yaml +rate_limit: + simple_strategy: + overrides: + cosmo_rate_limit:id_premium_user: + rate: 25 + burst: 50 + period: 1m + cosmo_rate_limit:id_trial_user: + rate: 2 + burst: 4 + period: 30s +``` + +Any fields you omit inherit from the base simple strategy configuration. This allows targeted tuning without duplicating the global defaults. ### Rate Limit Error Extension Code @@ -1876,13 +1905,22 @@ rate_limit: reject_exceeding_requests: false reject_status_code: 200 hide_stats_from_response_extension: false + overrides: + cosmo_rate_limit:id_paying_client: + rate: 20 + burst: 40 + period: 1m + cosmo_rate_limit:id_trial_client: + rate: 2 + burst: 2 + period: 30s storage: cluster_enabled: false urls: - "redis://localhost:6379" key_prefix: "cosmo_rate_limit" debug: false - key_suffix_expression: "" + key_suffix_expression: "request.auth.claims.client_id != nil ? 'id_' + request.auth.claims.client_id : ''" error_extension_code: enabled: true code: "RATE_LIMIT_EXCEEDED" diff --git a/docs/router/feature-flags.mdx b/docs/router/feature-flags.mdx new file mode 100644 index 00000000..c4eeb2bd --- /dev/null +++ b/docs/router/feature-flags.mdx @@ -0,0 +1,56 @@ +--- +title: "Feature Flags" +description: "Route traffic through alternate subgraphs by toggling feature flags per request." +icon: flag +sidebarTitle: Feature Flags +--- + +## Overview + +Router-level feature flags let you swap a subgraph at request time without a redeploy. Each flag defines a replacement subgraph. When a request includes the matching header or cookie, the router resolves the target subgraph to the flagged replacement. + + + For a primer on Cosmo feature flags and rollout strategies, see the [concepts guide](/concepts/feature-flags). + + +## Declare a Feature Flag + +Add the flag configuration in `router-compose.yaml`. Each flag defines one or more `feature_graphs` that describe the replacement subgraph to serve when the flag is active. + +```yaml router-compose.yaml +feature_flags: + - name: test_checkout + feature_graphs: + - name: checkout_canary + subgraph_name: checkout + routing_url: https://api.example.com/checkout-canary/graphql + schema: + file: feature-flag_checkout.graphql +subgraphs: + - name: checkout + routing_url: https://api.example.com/checkout/graphql + schema: + file: checkout.graphql +``` + +Key points: + +- `feature_flags[*].name` is the value you will send from the client (case sensitive). +- `feature_graphs[*].subgraph_name` must match the corresponding entry under `subgraphs` (`checkout` in the example). +- The router swaps the referenced `subgraph_name` with the replacement defined in `feature_graphs` when the flag is active. + + + Name feature flag schemas using the `feature-flag_*.graphql` convention and check in an empty placeholder subgraph file to keep composition predictable. + + +## Trigger the Flag + +Activate a flag by sending the header (or matching cookie) with the desired flag name. All requests that include the header are routed through the replacement subgraph. + +```http +GET /graphql HTTP/1.1 +Host: router.example.com +X-Feature-Flag: test_checkout +``` + +When the router receives `X-Feature-Flag: test_checkout`, it composes the operation against the replacement schema and forwards traffic to the routing URLs declared in the flag configuration.