Contexts

A Context is a uniquely-identified container of Feature values. Contexts, along with Features, are one of the most important resources you will work with when using featuresd.

What is a Context?

A Context is an object containing three pieces of data:

  • a key which uniquely identifies it,
  • a list of prototypes, which are the keys of other Contexts,
  • and a features map which maps the key of a Feature to a value.

Viewed in the HTTP API, a Context might appear like the following:

{
  "key": "user1",
  "prototypes": ["team1", "beta_testers"],
  "features": {
    "new_dropdown_appearance": "yes",
    "special_resource_limit": "8"
  }
}

Note that since prototypes are the keys of other Contexts, the example above implies that team1 and beta_testers are also Contexts that could be fetched via the API.

Contexts can be used to represent any entities in your application that you want to be able to attach features to. The most obvious example, which was used above, is that Contexts can represent users.

The code snippet above also demonstrates two other use-cases for Contexts:

  • teams or other organisations users may belong to;
  • ad-hoc categories of users like beta testers.

Because Contexts are so flexible, you can structure your data however you like. For example, if you want to toggle features based on a user's device (e.g., mobile app versus web), you might want to create a context for the specfic session, not the user account.

The prototype chain is how, for example, a session could inherit all the features defined for its user, its user's team, etc.

Feature values

Features themselves do not store any values; all values are stored in Contexts, often in the default Context.

The prototype chain

A Context can have zero or more other Contexts as its prototypes. When featuresd checks for the value of a Feature for a specific Context, it will first check in that specific Context, then check in all that Context's prototypes, until it finds a value for the Feature.

The order of prototypes is significant. In the example above, the protypes are listed as: ["team1", "beta_testers"]. This means that when searching for Features available to user1, Contexts will be checked in the following order:

overrideuser1team1beta_testersdefault

This effectively makes the features defined in the team1 context "more important" than those defined in the beta_testers Context.

(See the next section for more about the special default and override Contexts.)

Default and override

There are two special Contexts which are always part of all feature lookups. These are default and override.

When searching for a feature value, the override Context is always checked first. This allows you to globally override the values of specific features, for example in an emergency.

The default Context is always checked last. This lets operators set defaults which are obeyed only when a more specific value is not found in a Context lookup.

Comparison to other software

  • Flagsmith has Identities
  • LaunchDarkly has Users