@@ -14,9 +14,13 @@ import (
1414 "github.com/Flagsmith/flagsmith-go-client/v3/flagengine/segments"
1515 "github.com/Flagsmith/flagsmith-go-client/v3/internal/flaghttp"
1616
17- . "github.com/Flagsmith/flagsmith-go-client/v3/flagengine/identities/traits"
17+ enginetraits "github.com/Flagsmith/flagsmith-go-client/v3/flagengine/identities/traits"
1818)
1919
20+ type contextKey string
21+
22+ var contextKeyEvaluationContext = contextKey ("evaluationContext" )
23+
2024// Client provides various methods to query Flagsmith API.
2125type Client struct {
2226 apiKey string
@@ -44,8 +48,8 @@ func NewClient(apiKey string, options ...Option) *Client {
4448 }
4549
4650 c .client .SetHeaders (map [string ]string {
47- "Accept" : "application/json" ,
48- "X-Environment-Key" : c .apiKey ,
51+ "Accept" : "application/json" ,
52+ flaghttp . EnvironmentKeyHeader : c .apiKey ,
4953 })
5054 c .client .SetTimeout (c .config .timeout )
5155 c .log = createLogger ()
@@ -87,9 +91,34 @@ func NewClient(apiKey string, options ...Option) *Client {
8791
8892// Returns `Flags` struct holding all the flags for the current environment.
8993//
94+ // Provide `EvaluationContext` to evaluate flags for a specific environment or identity.
95+ //
9096// If local evaluation is enabled this function will not call the Flagsmith API
9197// directly, but instead read the asynchronously updated local environment or
9298// use the default flag handler in case it has not yet been updated.
99+ //
100+ // Notes:
101+ //
102+ // * `EvaluationContext.Environment` is ignored in local evaluation mode.
103+ //
104+ // * `EvaluationContext.Feature` is not yet supported.
105+ func (c * Client ) GetFlags (ctx context.Context , ec * EvaluationContext ) (f Flags , err error ) {
106+ if ec != nil {
107+ ctx = context .WithValue (ctx , contextKeyEvaluationContext , ec )
108+ if ec .Identity != nil {
109+ return c .GetIdentityFlags (ctx , ec .Identity .Identifier , mapIdentityEvaluationContextToTraits (* ec .Identity ))
110+ }
111+ }
112+ return c .GetEnvironmentFlags (ctx )
113+ }
114+
115+ // Returns `Flags` struct holding all the flags for the current environment.
116+ //
117+ // If local evaluation is enabled this function will not call the Flagsmith API
118+ // directly, but instead read the asynchronously updated local environment or
119+ // use the default flag handler in case it has not yet been updated.
120+ //
121+ // Deprecated: Use `GetFlags` instead.
93122func (c * Client ) GetEnvironmentFlags (ctx context.Context ) (f Flags , err error ) {
94123 if c .config .localEvaluation || c .config .offlineMode {
95124 if f , err = c .getEnvironmentFlagsFromEnvironment (); err == nil {
@@ -108,10 +137,6 @@ func (c *Client) GetEnvironmentFlags(ctx context.Context) (f Flags, err error) {
108137 return Flags {}, & FlagsmithClientError {msg : fmt .Sprintf ("Failed to fetch flags with error: %s" , err )}
109138}
110139
111- type GetIdentityFlagsOpts struct {
112- Transient bool `json:"transient,omitempty"`
113- }
114-
115140// Returns `Flags` struct holding all the flags for the current environment for
116141// a given identity.
117142//
@@ -122,13 +147,15 @@ type GetIdentityFlagsOpts struct {
122147// If local evaluation is enabled this function will not call the Flagsmith API
123148// directly, but instead read the asynchronously updated local environment or
124149// use the default flag handler in case it has not yet been updated.
125- func (c * Client ) GetIdentityFlags (ctx context.Context , identifier string , traits []* Trait , opts * GetIdentityFlagsOpts ) (f Flags , err error ) {
150+ //
151+ // Deprecated: Use `GetFlags` providing `EvaluationContext.Identity` instead.
152+ func (c * Client ) GetIdentityFlags (ctx context.Context , identifier string , traits []* Trait ) (f Flags , err error ) {
126153 if c .config .localEvaluation || c .config .offlineMode {
127154 if f , err = c .getIdentityFlagsFromEnvironment (identifier , traits ); err == nil {
128155 return f , nil
129156 }
130157 } else {
131- if f , err = c .GetIdentityFlagsFromAPI (ctx , identifier , traits , opts ); err == nil {
158+ if f , err = c .GetIdentityFlagsFromAPI (ctx , identifier , traits ); err == nil {
132159 return f , nil
133160 }
134161 }
@@ -180,7 +207,15 @@ func (c *Client) BulkIdentify(ctx context.Context, batch []*IdentityTraits) erro
180207// GetEnvironmentFlagsFromAPI tries to contact the Flagsmith API to get the latest environment data.
181208// Will return an error in case of failure or unexpected response.
182209func (c * Client ) GetEnvironmentFlagsFromAPI (ctx context.Context ) (Flags , error ) {
183- resp , err := c .client .NewRequest ().
210+ req := c .client .NewRequest ()
211+ maybeEc := ctx .Value (contextKeyEvaluationContext )
212+ if maybeEc != nil {
213+ envCtx := maybeEc .(* EvaluationContext ).Environment
214+ if envCtx != nil {
215+ req .SetHeader (flaghttp .EnvironmentKeyHeader , envCtx .APIKey )
216+ }
217+ }
218+ resp , err := req .
184219 SetContext (ctx ).
185220 ForceContentType ("application/json" ).
186221 Get (c .config .baseURL + "flags/" )
@@ -195,16 +230,27 @@ func (c *Client) GetEnvironmentFlagsFromAPI(ctx context.Context) (Flags, error)
195230
196231// GetIdentityFlagsFromAPI tries to contact the Flagsmith API to get the latest identity flags.
197232// Will return an error in case of failure or unexpected response.
198- func (c * Client ) GetIdentityFlagsFromAPI (ctx context.Context , identifier string , traits []* Trait , opts * GetIdentityFlagsOpts ) (Flags , error ) {
233+ func (c * Client ) GetIdentityFlagsFromAPI (ctx context.Context , identifier string , traits []* Trait ) (Flags , error ) {
199234 body := struct {
200235 Identifier string `json:"identifier"`
201236 Traits []* Trait `json:"traits,omitempty"`
202- GetIdentityFlagsOpts
237+ Transient * bool `json:"transient,omitempty"`
203238 }{Identifier : identifier , Traits : traits }
204- if opts != nil {
205- body .Transient = opts .Transient
239+ req := c .client .NewRequest ()
240+ maybeEc := ctx .Value (contextKeyEvaluationContext )
241+ if maybeEc != nil {
242+ ec := maybeEc .(* EvaluationContext )
243+ envCtx := ec .Environment
244+ if envCtx != nil {
245+ req .SetHeader (flaghttp .EnvironmentKeyHeader , envCtx .APIKey )
246+ }
247+ idCtx := ec .Identity
248+ if idCtx != nil {
249+ // `Identifier` and `Traits` had been set by `GetFlags` earlier.
250+ body .Transient = & idCtx .Transient
251+ }
206252 }
207- resp , err := c . client . NewRequest () .
253+ resp , err := req .
208254 SetBody (& body ).
209255 SetContext (ctx ).
210256 ForceContentType ("application/json" ).
@@ -295,7 +341,7 @@ func (c *Client) UpdateEnvironment(ctx context.Context) error {
295341}
296342
297343func (c * Client ) getIdentityModel (identifier string , apiKey string , traits []* Trait ) identities.IdentityModel {
298- identityTraits := make ([]* TraitModel , len (traits ))
344+ identityTraits := make ([]* enginetraits. TraitModel , len (traits ))
299345 for i , trait := range traits {
300346 identityTraits [i ] = trait .ToTraitModel ()
301347 }
0 commit comments