Gradual and experimental feature rollout with Feature Flags
An example of how feature flags could be used to release an experimental feature to a subset of a federated graph's consumers.
For an overview of what feature flags are and what they can achieve, see Feature Flags.
In this example, we are going to roll out a new, experimental feature in one of our services. However, we don't want this feature to be available to everyone immediately. Instead, it should be released gradually to only selected clients. This is functionality that can be achieved with feature flags.
Prerequisites
Before getting started with feature flags, please ensure the following:
You have created a federated graph that has been successfully composed with at least one published subgraph.
Getting started
This example will use the namespace "staging" for the CLI commands. If you are using the "default" namespace, you do not need to include any namespace parameters.
For this example, let's assume we have a federated graph, MyGraph
, with the label matchers team=A
. MyGraph
has been successfully composed with two published subgraphs, users
and products
, which both define the labels team=A
. Here are the schemas:
Users service SDL
Products service SDL
The Feature
The feature that we want to release is related to the products
service. We want to extend the current functionality thus:
Add a field that represents a shopping basket of products to the
User
entity.Add a mutation that allows products to be added to this new
basket
field.Add a field that represents a product name to the
Product
type.
Creating and publishing a Feature Subgraph
First, we must create a feature subgraph that will eventually compose our feature flag. This is done with wgc feature-subgraph create
. Every feature subgraph is linked to the "base" or "original" subgraph that it intends to replace. In this case, the feature we wish to gradually introduce to our customers is within the products
service, so we pass products
(the name of the service) to the --subgraphs
parameter.
Feature subgraphs do not define labels. Only feature flags (one or more feature subgraphs compose a feature flag) define labels, and those labels dictate to which federated graph(s) the feature flag applies.
After the new feature has been implemented and the corresponding service has been deployed, the new schema need to be published. The schema might look like so:
Products-feature service SDL
The schema for products-feature
can be published using wgc subgraph publish
:
No new compositions will be triggered yet, because the feature subgraph is not yet part of a feature flag.
Feature subgraphs do not work in isolation! To be applied to a federated graph, a feature subgraph must compose a feature flag, which itself must be enabled.
Creating and enabling a Feature Flag
To apply our feature subgraph(s) to our federated graph(s), they must first compose a feature flag. A feature flag is a collection of one or more feature subgraphs. When a feature flag is enabled, each feature subgraph that composes that feature flag will also become active. Similarly, if a feature flag is disabled, its constituent feature subgraphs will also become inactive.
Note that each feature flag is bespoke, and a feature subgraph can belong to more than one feature flag. Toggling one feature flag does not affect another, even if there is overlap in the feature subgraphs that compose them.
A feature flag can be created using wgc feature-flag create
. A feature flag must be created with the provision of at least one space-delimited feature subgraph name to the --feature-subgraphs
parameter. Defining labels with the --label
parameter dictates to which federated graphs the feature flag applies. Lastly, feature flags are disabled upon creation by default, unless the --enabled
flag is passed. Note that in the example command below, the labels match the label matchers of the federated graph MyGraph
.
Because my-flag
was created with the --enabled
flag, it will be enabled (activated) immediately upon creation. Consequently, two new compositions should have been triggered: a recomposition of the base federated graph and a composition that includes the enabled feature flag.
A successful feature flag composition will produce an embedded feature flag configuration within the base router execution configuration.
If either the federated graph base composition or the feature flag composition is unsuccessful, the feature flag configuration will not be produced (or accessible) to the router.
Using Cosmo Router to serve the Feature Flag to clients
The new feature has been implemented, deployed, published, and made accessible to your Cosmo router. Now all that's left is instructing your router to serve the feature flag to your selected clients. Luckily, this is as easy as setting a header or a cookie in the request:
If both the feature flag header and cookie are set, the feature flag header will take precedence. If the feature flag can't be found, we will fallback to the default federated graph.
Feature Flag Header
Header | Value |
---|---|
X-Feature-Flag | Name of the feature flag |
A request to the federated graph feature flag will be made if the name of a valid feature flag is passed to the X-Feature-Flag
header. If the name of the feature flag is invalid, the default federated graph will be served. An example is shown below:
Cookie
Header | Value |
---|---|
Cookie | feature_flag={name of the feature flag} |
A request to the federated graph feature flag will be made if the name of a valid feature flag is provided to the Cookie
header in the format feature_flag={name of the feature flag}
. If the name of the feature flag is invalid, the default federated graph will be served. An example is shown below:
Now, whenever the cookie or header are provided, the client will be able to use the new features, i.e., request the Product.name
field or mutate a User
with addProductToUserBasket
. When the header or cookie is not included, the base (non-feature flag) federated graph will be served.
Last updated