launchdarkly / openfeature-node-server

An open feature provider for the LaunchDarkly node SDK.
Other
10 stars 3 forks source link

Feature/defaultContext #19

Closed AlanyTan closed 1 year ago

AlanyTan commented 1 year ago

Requirements

Related issues N/A Provide links to any issues in this repository or elsewhere relating to this pull request.

Describe the solution you've provided

When openfeatureClient.getValue functions are called, context was mandatory. However, in many use cases, context was either irrelevant or not available, we would like to be able to call the getValue without providing context.

A default context with {key:"OpenFeature default", anonymous:true} is added when context was not provided when calling the get functions.

Describe alternatives you've considered

Use the setTransactionContextPropagator function to set default transaction level context. However that is an experimental feature of OpenFeature and is not reliable enough for actual production use.

Additional context

Add any other context about the pull request here.

kinyoklion commented 1 year ago

Hey @AlanyTan,

This type of global context manipulation can be handled be registering hooks with the OpenFeature SDK. You can use a global before hook to check the context and create an anonymous one.

Do this before you start doing evaluations:

class AnonymousDefaultContext implements Hook {
  before(hookContext: BeforeHookContext, hookHints?: Readonly<Record<string, unknown>> | undefined):
    void | EvaluationContext | Promise<void | EvaluationContext> {
      if (Object.entries(hookContext.context).length === 0) {
        return { targetingKey: 'OpenFeature default', anonymous: true };
      }
  }
}

OpenFeature.addHooks(new AnonymousDefaultContext());

It would be too substantial of a deviation from LD behavior to include as a function of the provider. It is, however, where OpenFeature hooks excel.

Thank you, Ryan

kinyoklion commented 1 year ago

There are some other alternatives as well, you can set a global context, and override properties when you want to do a specific evaluation. Or you could set an anonymous context on a client, and then use that specific client for anonymous evaluations.

OpenFeature.setContext(anonContext);

const client = OpenFeature.getClient();
client.setContext(anonContext);

Thanks, Ryan