4. Hooks
Overview
Hooks are a mechanism whereby application developers can add arbitrary behavior to flag evaluation. They operate similarly to middleware in many web frameworks.
Hooks add their logic at any of four specific stages of flag evaluation:
before, immediately before flag evaluationafter, immediately after successful flag evaluationerror, immediately after an unsuccessful during flag evaluationfinallyunconditionally after flag evaluation
Hooks can be configured to run globally (impacting all flag evaluations), per client, or per flag evaluation invocation. Some example use-cases for hook include adding additional data to the evaluation context, performing validation on the received flag value, providing data to telemetric tools, and logging errors.
Definitions
Hook: Application author/integrator-supplied logic that is called by the OpenFeature framework at a specific stage. Stage: An explicit portion of the flag evaluation lifecycle. e.g. before being "before the resolution is run. Invocation: A single call to evaluate a flag. client.getBooleanValue(..) is an invocation. API: The global API singleton.
4.1. Hook context
Hook context exists to provide hooks with information about the invocation.
Requirement 4.1.1
Hook context MUST provide: the
flag key,flag value type,evaluation context, and thedefault value.
Requirement 4.1.2
The
hook contextSHOULD provide: access to theclient metadataand theprovider metadatafields.
Requirement 4.1.3
The
flag key,flag type, anddefault valueproperties MUST be immutable. If the language does not support immutability, the hook MUST NOT modify these properties.
Condition 4.1.4
The implementation uses the dynamic-context paradigm.
Conditional Requirement 4.1.4.1
The evaluation context MUST be mutable only within the
beforehook.
4.2. Hook Hints
Requirement 4.2.1
hook hintsMUST be a structure supports definition of arbitrary properties, with keys of typestring, and values of typeboolean | string | number | datetime | structure..
Condition 4.2.2
The implementation language supports a mechanism for marking data as immutable.
Conditional Requirement 4.2.2.1
Condition:
Hook hintsMUST be immutable.
Conditional Requirement 4.2.2.2
Condition: The client
metadatafield in thehook contextMUST be immutable.
Conditional Requirement 4.2.2.3
Condition: The provider
metadatafield in thehook contextMUST be immutable.
4.3. Hook creation and parameters
Requirement 4.3.1
Hooks MUST specify at least one stage.
Condition 4.3.2
The implementation uses the dynamic-context paradigm.
Conditional Requirement 4.3.2.1
The
beforestage MUST run before flag resolution occurs. It accepts ahook context(required) andhook hints(optional) as parameters and returns either anevaluation contextor nothing.
EvaluationContext | void before(HookContext hookContext, HookHints hints);
Condition 4.3.3
The implementation uses the static-context paradigm.
Conditional Requirement 4.3.3.1
The
beforestage MUST run before flag resolution occurs. It accepts ahook context(required) andhook hints(optional) as parameters. It has no return value.
void before(HookContext hookContext, HookHints hints);
Requirement 4.3.4
Any
evaluation contextreturned from abeforehook MUST be passed to subsequentbeforehooks (viaHookContext).
Requirement 4.3.5
When
beforehooks have finished executing, any resultingevaluation contextMUST be merged with the existingevaluation context.
Evaluation context merge order is defined in Context levels and merging.
Requirement 4.3.6
The
afterstage MUST run after flag resolution occurs. It accepts ahook context(required),flag evaluation details(required) andhook hints(optional). It has no return value.
Requirement 4.3.7
The
errorhook MUST run when errors are encountered in thebeforestage, theafterstage or during flag resolution. It acceptshook context(required),exceptionrepresenting what went wrong (required), andhook hints(optional). It has no return value.
Requirement 4.3.8
The
finallyhook MUST run after thebefore,after, anderrorstages. It accepts ahook context(required) andhook hints(optional). There is no return value.
Condition 4.3.9
finallyis a reserved word in the language.
Conditional Requirement 4.3.9.1
Instead of
finally,finallyAfterSHOULD be used.
4.4. Hook registration & ordering
Requirement 4.4.1
The API, Client, Provider, and invocation MUST have a method for registering hooks.
OpenFeature.addHooks(new Hook1());
//...
Client client = OpenFeature.getClient();
client.addHooks(new Hook2());
`
//...
client.getValue('my-flag', 'defaultValue', new Hook3());
Requirement 4.4.2
Hooks MUST be evaluated in the following order:
- before: API, Client, Invocation, Provider
- after: Provider, Invocation, Client, API
- error (if applicable): Provider, Invocation, Client, API
- finally: Provider, Invocation, Client, API
Requirement 4.4.3
If a
finallyhook abnormally terminates, evaluation MUST proceed, including the execution of any remainingfinallyhooks.
In languages with try/catch semantics, this means that exceptions thrown in finally hooks should be caught, and not propagated up the call stack.
Requirement 4.4.4
If an
errorhook abnormally terminates, evaluation MUST proceed, including the execution of any remainingerrorhooks.
In languages with try/catch semantics, this means that exceptions thrown in error hooks should be caught, and not propagated up the call stack.
Requirement 4.4.5
If an error occurs in the
beforeorafterhooks, theerrorhooks MUST be invoked.
Requirement 4.4.6
If an error occurs during the evaluation of
beforeorafterhooks, any remaining hooks in thebeforeorafterstages MUST NOT be invoked.
Requirement 4.4.7
If an error occurs in the
beforehooks, the default value MUST be returned.
Before hooks can impact evaluation by various means, such as mutating the evaluation context. Therefore, an error in the before hooks is considered abnormal execution, and the default should be returned.
Flag evaluation options
Usage might look something like:
val = client.get_boolean_value('my-key', False, evaluation_options={
'hooks': new MyHook(),
'hook_hints': {'side-item': 'onion rings'}
})
Requirement 4.5.1
Flag evaluation optionsMAY containhook hints, a map of data to be provided to hook invocations.
Requirement 4.5.2
hook hintsMUST be passed to each hook.
Requirement 4.5.3
The hook MUST NOT alter the
hook hintsstructure.