go-sdk
go-sdk copied to clipboard
[FEATURE] Implement transaction context
We should implement transaction context propagation
What is transaction context?
From the spec: Transaction context is a container for transaction-specific evaluation context (e.g. user id, user agent, IP). Transaction context can be set where specific data is available (e.g. an auth service or request handler) and by using the transaction context propagator it will automatically be applied to all flag evaluations within a transaction (e.g. a request or thread).
Transaction context has been added in the following PR: https://github.com/open-feature/spec/pull/227
Examples:
Implementation
The JS SDK implementation is implemented as a POC that is currently being hardened. https://github.com/open-feature/js-sdk/blob/main/packages/server/src/transaction-context/transaction-context.ts
Usage
An example usage for the JS SDK implementation of the feature is the usage for propagating HTTP request information in the NestJS SDK. https://github.com/open-feature/js-sdk/blob/main/packages/nest/src/evaluation-context-interceptor.ts#L31
Is it expected that the user pass down the context? Because I'm not sure there's a trivial way in Go to have a context for a function call which isn't passed to it.
It's possible to create a context.Context
which has our TransactionContext
as a value and require the user to use the context.Context
when getting the feature flag:
// Creating the context
ctx := NewTransactionContext(context.Background(), map[string]int{"userID": 12345})
next(ctx)
// Using the context
client.BooleanValue(ctx, flag, defaultValue)
The implementation would be something like:
func NewTransactionContext(ctx context.Context, attributes map[string]interface{}) {
return context.WithValue(ctx, "transactioncontext", attributes)
}
func (c *Client) BooleanValue(ctx context.Context, flag string, defaultValue bool, options ...Option) {
transactionContext := ctx.Value("transactioncontext")
...
}
@yardenlaif thanks for the interest in this issue :)
Is it expected that the user pass down the context?
Yes, context should be expected to be provided by the user. This maps with our current flag evaluation methods.
It's possible to create a context.Context which has our TransactionContext
+1 and we should expose it from openfeature api [1]
// Derive transaction context
openfeature.SetTransactionContext(ctx, value)
Regarding the key, use an empty struct instead of a string. For example, context.WithValue(ctx, key{}, "bla")
where key is an empty struct to avoid hijacking.
[1] - https://github.com/open-feature/go-sdk?tab=readme-ov-file#usage
Thanks @Kavindu-Dodan! @lukas-reining @thomaspoignant do you have anything to add?
To me this looks like a plan @beeme1mr @Kavindu-Dodan @yardenlaif :)
Yep, agreed. I think this is the idiom I would expect in Go.