Giter VIP home page Giter VIP logo

sdk-research's Introduction

OpenFeature API and SDK Experimentation

experimental

The purpose of this repository is to experiment with different techniques in order to help define the initial spec of OpenFeature. It was inspired by the OpenTelemetry SDK, with a focus on the design principles outlined in the spec. These experiments were written in TypeScript and focus on NodeJS, but the basic concepts should be language agnostic.

Getting started

To run the demo scenarios described on this page, please make sure you have the following prerequisites configured on your system.

  • Git
  • NodeJS 14 or later
  • Docker

You can then clone the repo and install the dependencies.

  1. clone the repo: git clone https://github.com/open-feature/sdk-research.git
  2. Install dependencies: npm ci

Available demos:

Simple API

A core design principle of OpenFeature is a simple, understandable API. OpenFeature's API needs to be flexible enough to handle all the common use cases of feature flags while being easy to work with. In order to support this, a common API needs to be defined that's capable of supporting core feature flagging use cases. The method names and signatures still need to be agreed upon by the community, but a basic implementation can be found here.

Global Singleton

Inspired by OpenTelemetry, this experimental SDK registers itself globally. Typically doing this is discouraged but, in this case, it provides interesting flexibility. It allows library maintainers to include OpenFeature in their project, even if they're running a different, but compatible version of OpenFeature. An example of how this could be used can be found in the Fibonacci library.

Provider Registration

OpenFeature allows developers to register a provider. Providers are responsible for using the flag identity and context to determine the state of the feature. If no providers are registered, the flags will no-op and return the default value.

No-op Demo

To see this in action, we'll run the API app found here. Notice that we're using OpenFeature but not registering a provider. Let's run the app and see what happens.

  1. Run npm run no-op-demo
  2. Open http://localhost:3333/api in your browser

That's it! You should see Welcome to the api!. Unfortunately, that's all you can do without registering a provider. Thankfully, as we'll see in the next section, that part is easy.

Compatibility

Another key design principle of OpenFeature is compatibility with existing open source and commercial feature flag offerings. It should be possible to register a feature flag provider that's responsible for handling the flag evaluation. Only a single provider can be registered at a time and not providing one will cause flag evaluations to return the default value. This can be tested by running the application without registering a provider. In order to support existing SDKs, an adaptor can be created that conforms to the provider's interface.

NOTE: You may notice that the demos below don't register providers directly in the app. This is done before the main app starts using the -r node cli argument. The config can be found here.

Environment Variable Provider Demo

The environment variable provider is a simple demo showing how environment variables could be used make flag evaluations. Its purpose is to show how a provider could be implemented.

Follow these steps to run the demo:

  1. copy .env.example to .env
  2. Run npm run env-var-demo
  3. Open http://localhost:3333/api in your browser

You should see Welcome to the api! just as before. Now, change the value of new-welcome-message to true and restart the app. It should show Welcome to the next gen api! in your browser. Now we're getting somewhere, but it's still a bit too basic to be useful. The next demo will show how we could register a commercial feature flag tool using an existing SDK and an OpenFeature Adaptor.

Split Adaptor Demo

The Split adaptor shows how an existing SDK, in this case Split's NodeJS SDK, can be used in OpenFeature. This is a simple example that doesn't cover every use case that Split offers, but the goal would be to support as many features as possible.

Follow these steps to run the demo:

  1. Copy .env.example to .env
  2. Add a Split.io service-side API key to the SPLIT_KEY in the .env file.
  3. Create a new split called new-welcome-message with the default treatments
  4. Create a new split called fib-algo with the treatment values: recursive, memo, loop, binet, and default.
  5. Run npm run split-demo

You can now remotely configure the welcome message and the algorithm used in the Fibonacci library. The Fibonacci example is particularly interesting because registers a library-specific client. This would allow maintainers to include feature flagging in their libraries that could be remotely configured if desired. Also, if no provider is registered, the library will no-op and simply use the default algorithm.

Experiment with different Fibonacci algorithms and hitting the API with these values:

Now, wouldn't it be nice if you could visually see the impact an algorithm had on a request? That's where OpenTelemetry support comes in.

OpenTelemetry Support

Supporting OpenTelemetry natively in OpenFeature provides a number of advantages. The most obvious benefit is distributed traces would contain feature flag information. This would make it easy to determine the impact a feature or features had on a single request. Other features, such as baggage and request scoped context, may be useful options in the future.

OpenTelemetry is not required to use OpenFeature. Similar to OpenFeature, if a provider is not registered, the library no-ops. That means you are able to take advantage of all the great features of OpenTelemetry if you already use it, with minimal overhead if you don't.

OpenTelemetry Demo

  1. Start Zipkin in Docker: docker run --rm -d -p 9411:9411 --name zipkin openzipkin/zipkin
  2. Open http://localhost:9411/ in your browser
  3. Start one of the demos above or run npm run no-op-demo
  4. Open Zipkin and search for a trace

Zipkin

Baggage

OpenTelemetry supports the w3c baggage standard by default. Extensive testing of baggage was out of scope for this experiment, but it's worth mentioning the potential value it could provide. Baggage is a set of user-defined properties that are associated with a request across a distributed system. In the context of a feature flag, it could be useful for evaluation caching or passing useful context to downstream services.

The implementation of baggage in the node.js SDK is low level and not well documented. Baggage is also immutable according to the OpenTelemetry spec.

The following example shows a baggage could be created or extended in an express middleware function. OpenFeature could then read baggage and merge it with existing context.

app.use(async (req, res, next) => {
  const key = 'new-welcome-message';
  const value = 'true';
  const baggage = propagation.getBaggage(context.active());
  context.with(
    propagation.setBaggage(
      context.active(),
      baggage
        ? baggage.setEntry(key, { value })
        : propagation.createBaggage({ [key]: { value } })
    ),
    next
  );
});

It's also possible to set the header key baggage with a value like foo=bar. OpenTelemetry will then pass this value via baggage through the entire request. This could be used in OpenFeature to explicitly enable a feature flag using a header.

Open Questions

  • How should a provider that requires an async start-up be handled?
  • What should happen if multiple providers are registered?
  • Could something similar to an OpenAPI be used to describe feature flags in code?
  • What OpenTelemetry semantic naming prefix should be used?
  • Can we cache flag evaluation using the trace ID?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.