flagsmith

package module
v5.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2026 License: BSD-3-Clause Imports: 28 Imported by: 0

README

Go GoReportCard GoDoc

Flagsmith Go SDK

Flagsmith allows you to manage feature flags and remote config across multiple projects, environments and organisations.

This is the SDK for go for https://flagsmith.com/.

Adding to your project

For full documentation visit https://docs.flagsmith.com/clients/server-side?language=go.

Experimentation

Enable events with WithEvents. Its context runs the background sender, and cancelling it is the shutdown flush.

eventsCtx, stopEvents := context.WithCancel(context.Background())
client := flagsmith.NewClient(os.Getenv("FLAGSMITH_SERVER_KEY"), flagsmith.WithEvents(eventsCtx))

ec := flagsmith.NewEvaluationContext("user-123", map[string]interface{}{"plan": "premium"})
flag, err := client.GetExperimentFlag(ctx, "checkout_cta", ec)

GetExperimentFlag returns the flag and records a $flag_exposure when the identity is enrolled in a running experiment. Experiment metadata needs remote evaluation, so local evaluation records no exposure. TrackExposureEvent records one for a flag you evaluated some other way.

Record conversions with TrackEvent. Names starting with $ are reserved.

err = client.TrackEvent("purchase", &flagsmith.EventOptions{Identifier: "user-123", Value: 49.99})
Delivery and failure handling

Events are sent every 10 seconds (WithEventsFlushInterval) or when 1000 are buffered (WithEventsMaxBufferSize). Failures never reach the code that tracks events.

  • Network errors, timeouts and 408, 429, 502, 503 and 504 are retried: three attempts, backoff from 1 second (WithEventsRetryBackoff) doubling to 10 seconds, with full jitter. A batch that still fails goes back to the front of the buffer until the next scheduled send or FlushEvents.
  • Any other error status, including 500, drops the batch.
  • A 401 or 403 stops event tracking, drops the buffer and logs one warning, until the client is re-created. Flags keep working.
  • One scheduled send is in flight at a time. When the buffer is full meanwhile, the oldest events are dropped.
  • Events a 202 lists as rejected are logged by index and not resent.
  • Equal exposures are sent once until the batch carrying them succeeds.
  • Traits and metadata are captured when tracked. Values that cannot be encoded as JSON drop the event.
  • GetExperimentFlag sends the identity's traits, transient ones included. It and TrackExposureEvent return an error for a blank identifier; TrackEvent sends one as none.
  • The events request carries the SDK's own environment key and user agent. WithCustomHeaders is not applied to it.
  • Logs never include identifiers, trait values or response content.

DroppedEvents returns a running count of events lost in any of these ways, including at shutdown.

Events cannot be used with WithOfflineMode.

Shutdown

Cancelling the WithEvents context sends what is buffered, retrying only within one request timeout. The same deadline cuts sends already in progress, including FlushEvents. Anything left is dropped and counted.

For a guarantee, for example in a CLI tool, job or serverless function, call FlushEvents with a deadline before exit. It returns once every event tracked before the call has been sent, kept for retry or dropped.

flushCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := client.FlushEvents(flushCtx); err != nil {
	log.Printf("flushing Flagsmith events: %v", err)
}
stopEvents()

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Getting Help

If you encounter a bug or feature request we would like to hear about it. Before you submit an issue please search existing issues in order to prevent duplicates.

Get in touch

If you have any questions about our projects you can email support@flagsmith.com.

Documentation

Index

Constants

View Source
const (
	// Number of seconds to wait for a request to
	// complete before terminating the request.
	DefaultTimeout = 10 * time.Second

	// Default base URL for the API.
	DefaultBaseURL = "https://edge.api.flagsmith.com/api/v1/"

	BulkIdentifyMaxCount   = 100
	DefaultRealtimeBaseUrl = "https://realtime.flagsmith.com/"
)
View Source
const (
	// DefaultEventsBaseURL is the base URL of Flagsmith's events API.
	DefaultEventsBaseURL = "https://events.api.flagsmith.com/"
	// DefaultEventsFlushInterval is how often buffered events are sent.
	DefaultEventsFlushInterval = 10 * time.Second
	// DefaultEventsMaxBufferSize is the buffer size that triggers a send, and its limit.
	DefaultEventsMaxBufferSize = 1000
	// DefaultEventsRetryBackoff is the backoff before the first retry of a failed batch.
	DefaultEventsRetryBackoff = time.Second
	// FlagExposureEvent is the event recorded when an identity is exposed to a variant.
	FlagExposureEvent = "$flag_exposure"
)
View Source
const (
	OptionWithHTTPClient  = "WithHTTPClient"
	OptionWithRestyClient = "WithRestyClient"
)
View Source
const AnalyticsEndpoint = "analytics/flags/"
View Source
const AnalyticsTimerInMilli = 10 * 1000
View Source
const EnvironmentKeyHeader = "X-Environment-Key"

Variables

This section is empty.

Functions

func WithEvaluationContext

func WithEvaluationContext(ctx context.Context, ec EvaluationContext) context.Context

Returns context with provided EvaluationContext instance set.

Types

type AnalyticsProcessor

type AnalyticsProcessor struct {
	// contains filtered or unexported fields
}

func NewAnalyticsProcessor

func NewAnalyticsProcessor(ctx context.Context, client *resty.Client, baseURL string, timerInMilli *int, log Logger) *AnalyticsProcessor

func (*AnalyticsProcessor) Flush

func (a *AnalyticsProcessor) Flush(ctx context.Context) error

func (*AnalyticsProcessor) TrackFeature

func (a *AnalyticsProcessor) TrackFeature(featureName string)

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client provides various methods to query Flagsmith API.

func NewClient

func NewClient(apiKey string, options ...Option) *Client

NewClient creates instance of Client with given configuration.

func (*Client) BulkIdentify

func (c *Client) BulkIdentify(ctx context.Context, batch []*IdentityTraits) error

BulkIdentify can be used to create/overwrite identities(with traits) in bulk NOTE: This method only works with Edge API endpoint.

func (*Client) DroppedEvents added in v5.3.0

func (c *Client) DroppedEvents() int64

DroppedEvents returns how many experimentation events have been lost so far. The count only increases; the README lists what it counts. Returns 0 when events are not enabled.

func (*Client) ExtractNextPage added in v5.1.0

func (c *Client) ExtractNextPage(linkHeader string) string

ExtractNextPage parses the Link header from the environment-document API and returns the decoded page_id value when a next page exists, or empty string otherwise. Expected format: </api/v1/environment-document/?page_id=xxx>; rel="next".

func (*Client) FlushEvents added in v5.3.0

func (c *Client) FlushEvents(ctx context.Context) error

FlushEvents sends buffered events and returns once every event tracked before the call has been sent, kept for retry or dropped, or when ctx ends. Call it with a deadline before a short-lived process exits. Returns nil when events are not enabled.

func (*Client) GetEnvironmentFlags

func (c *Client) GetEnvironmentFlags(ctx context.Context) (f Flags, err error)

GetEnvironmentFlags calls GetFlags using the current environment as the EvaluationContext. Equivalent to GetFlags(ctx, nil).

func (*Client) GetEnvironmentFlagsFromAPI

func (c *Client) GetEnvironmentFlagsFromAPI(ctx context.Context) (Flags, error)

GetEnvironmentFlagsFromAPI tries to contact the Flagsmith API to get the latest environment data. Will return an error in case of failure or unexpected response.

func (*Client) GetExperimentFlag added in v5.3.0

func (c *Client) GetExperimentFlag(ctx context.Context, featureName string, ec EvaluationContext) (Flag, error)

GetExperimentFlag evaluates one flag for the identity in ec and records an exposure when that identity is enrolled in a running experiment, which requires remote evaluation. See the README's Experimentation section. Requires WithEvents and an identity in ec, and returns an error if ec targets another environment.

func (*Client) GetFlags

func (c *Client) GetFlags(ctx context.Context, ec *EvaluationContext) (f Flags, err error)

GetFlags evaluates the feature flags within an EvaluationContext.

When flag evaluation fails, the value of each Flag is determined by the default flag handler from WithDefaultHandler, if one was provided.

Flags are evaluated remotely by the Flagsmith API by default. To evaluate flags locally, instantiate a client using WithLocalEvaluation.

func (*Client) GetIdentityFlags

func (c *Client) GetIdentityFlags(ctx context.Context, identifier string, traits []*Trait) (f Flags, err error)

GetIdentityFlags calls GetFlags using this identifier and traits as the EvaluationContext.

func (*Client) GetIdentityFlagsFromAPI

func (c *Client) GetIdentityFlagsFromAPI(ctx context.Context, identifier string, traits []*Trait) (Flags, error)

GetIdentityFlagsFromAPI tries to contact the Flagsmith API to get the latest identity flags. Will return an error in case of failure or unexpected response.

func (*Client) GetIdentitySegments

func (c *Client) GetIdentitySegments(identifier string, traits []*Trait) ([]*segments.SegmentModel, error)

Returns an array of segments that the given identity is part of.

func (*Client) TrackEvent added in v5.3.0

func (c *Client) TrackEvent(name string, opts *EventOptions) error

TrackEvent buffers a custom event, such as a conversion; opts may be nil. Names starting with "$" are reserved. Requires WithEvents; see the README's Experimentation section.

func (*Client) TrackExposureEvent added in v5.3.0

func (c *Client) TrackExposureEvent(featureName string, identifier string, value interface{}, opts *EventOptions) error

TrackExposureEvent buffers a $flag_exposure for a flag evaluated elsewhere. It returns an error without an identifier, and reads only Traits and Metadata from opts, which may be nil. Requires WithEvents; see the README's Experimentation section.

func (*Client) UpdateEnvironment

func (c *Client) UpdateEnvironment(ctx context.Context) error

type EnvironmentEvaluationContext

type EnvironmentEvaluationContext struct {
	// APIKey is an identifier for this environment. It is also known as the environment ID or client-side SDK key.
	APIKey string `json:"api_key"`
}

EnvironmentEvaluationContext represents a Flagsmith environment used in an EvaluationContext. It is ignored if the evaluating Client was created using WithLocalEvaluation.

type EvaluationContext

type EvaluationContext struct {
	Environment *EnvironmentEvaluationContext `json:"environment,omitempty"`
	Identity    *IdentityEvaluationContext    `json:"identity,omitempty"`
	Feature     *FeatureEvaluationContext     `json:"feature,omitempty"`
}

EvaluationContext represents a context in which feature flags can be evaluated. Flagsmith flags are always evaluated in an EnvironmentEvaluationContext, with an optional IdentityEvaluationContext.

func GetEvaluationContextFromCtx

func GetEvaluationContextFromCtx(ctx context.Context) (ec EvaluationContext, ok bool)

Retrieve EvaluationContext instance from context.

func NewEvaluationContext

func NewEvaluationContext(identifier string, traits map[string]interface{}) EvaluationContext

func NewTransientEvaluationContext

func NewTransientEvaluationContext(identifier string, traits map[string]interface{}) EvaluationContext

type EventOptions added in v5.3.0

type EventOptions struct {
	Identifier string
	Value      interface{}
	Traits     map[string]interface{}
	Metadata   map[string]interface{}
}

EventOptions carries the optional fields of an event. Values are captured when tracked.

type EventProcessor added in v5.3.0

type EventProcessor struct {
	// contains filtered or unexported fields
}

EventProcessor buffers experimentation events and sends them in batches. See the README's Experimentation section for delivery and failure handling.

func NewEventProcessor added in v5.3.0

func NewEventProcessor(ctx context.Context, client *resty.Client, eventsBaseURL string, maxBufferSize int, flushInterval time.Duration, timeout time.Duration, log *slog.Logger) *EventProcessor

NewEventProcessor starts an EventProcessor whose worker exits when ctx is done.

func (*EventProcessor) DroppedEvents added in v5.3.0

func (p *EventProcessor) DroppedEvents() int64

DroppedEvents returns how many events have been lost so far.

func (*EventProcessor) Flush added in v5.3.0

func (p *EventProcessor) Flush(ctx context.Context) error

Flush sends buffered events and waits for the batches in flight when it was called.

func (*EventProcessor) TrackEvent added in v5.3.0

func (p *EventProcessor) TrackEvent(name string, opts *EventOptions)

TrackEvent buffers a custom event. opts may be nil.

func (*EventProcessor) TrackExposureEvent added in v5.3.0

func (p *EventProcessor) TrackExposureEvent(featureName string, identifier string, value interface{}, traits map[string]interface{}, metadata map[string]interface{})

TrackExposureEvent buffers a $flag_exposure event; it is ignored without an identifier.

type ExperimentMetadata added in v5.3.0

type ExperimentMetadata struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
	// InExperiment reports whether this identity is enrolled. Variant alone cannot
	// tell: outside the rollout an identity still gets a variant.
	InExperiment bool `json:"in_experiment"`
}

ExperimentMetadata describes the running experiment a flag was evaluated under. It is only populated by remote identity evaluation.

type FeatureEvaluationContext

type FeatureEvaluationContext struct {
	Name string `json:"name"`
}

FeatureEvaluationContext is not yet implemented.

type Flag

type Flag struct {
	Enabled     bool
	Value       interface{}
	IsDefault   bool
	FeatureID   int
	FeatureName string
	// Reason is the evaluation reason, e.g. "DEFAULT", "SPLIT; weight=70.0" or
	// "TARGETING_MATCH; segment=...". Empty when none was reported.
	Reason string
	// Variant is the key of the multivariate variant the identity was bucketed into.
	// Empty for standard features and evaluation without an identity.
	Variant string
	// Experiment is the running experiment on this feature. Only populated by remote
	// identity evaluation; nil otherwise.
	Experiment *ExperimentMetadata
}

type Flags

type Flags struct {
	// contains filtered or unexported fields
}

func (*Flags) AllFlags

func (f *Flags) AllFlags() []Flag

Returns an array of all flag objects.

func (*Flags) GetFeatureValue

func (f *Flags) GetFeatureValue(featureName string) (interface{}, error)

Returns the value of a particular flag.

func (*Flags) GetFlag

func (f *Flags) GetFlag(featureName string) (Flag, error)

Returns a specific flag given the name of the feature.

func (*Flags) IsFeatureEnabled

func (f *Flags) IsFeatureEnabled(featureName string) (bool, error)

Returns a boolean indicating whether a particular flag is enabled.

type FlagsmithAPIError

type FlagsmithAPIError struct {
	Msg                string
	Err                error
	ResponseStatusCode int
	ResponseStatus     string
}

func (FlagsmithAPIError) Error

func (e FlagsmithAPIError) Error() string

type FlagsmithClientError

type FlagsmithClientError struct {
	// contains filtered or unexported fields
}

func (FlagsmithClientError) Error

func (e FlagsmithClientError) Error() string

type IdentityEvaluationContext

type IdentityEvaluationContext struct {
	Identifier *string                            `json:"identifier,omitempty"`
	Traits     map[string]*TraitEvaluationContext `json:"traits,omitempty"`
	Transient  *bool                              `json:"transient,omitempty"`
}

IdentityEvaluationContext represents a Flagsmith identity within a Flagsmith environment, used in an EvaluationContext. Traits are application-defined key-value pairs which can be used as part of the flag evaluation context. Flagsmith will not persist Transient identities when flags are remotely evaluated.

type IdentityTraits

type IdentityTraits struct {
	Identifier string         `json:"identifier"`
	Traits     []*trait.Trait `json:"traits"`
	Transient  bool           `json:"transient,omitempty"`
}

type LocalFileHandler

type LocalFileHandler struct {
	// contains filtered or unexported fields
}

func NewLocalFileHandler

func NewLocalFileHandler(environmentDocumentPath string) (*LocalFileHandler, error)

NewLocalFileHandler creates a new LocalFileHandler with the given path.

func (*LocalFileHandler) GetEnvironment

func (handler *LocalFileHandler) GetEnvironment() *environments.EnvironmentModel

type Logger

type Logger interface {
	// Errorf logs an error message with the given format and arguments.
	Errorf(format string, v ...interface{})

	// Warnf logs a warning message with the given format and arguments.
	Warnf(format string, v ...interface{})

	// Debugf logs a debug message with the given format and arguments.
	Debugf(format string, v ...interface{})
}

Logger is the interface used for logging by flagsmith client. This interface defines the methods that a logger implementation must implement. It is used to abstract logging and enable clients to use any logger implementation they want.

type OfflineHandler

type OfflineHandler interface {
	GetEnvironment() *environments.EnvironmentModel
}

type Option

type Option func(c *Client)

func WithAnalytics

func WithAnalytics(ctx context.Context) Option

WithAnalytics enables tracking of the usage of the Feature flags.

The goroutine responsible for asynchronously uploading the locally stored cache uses the context provided here, which means that if it expires the background process will exit.

func WithBaseURL

func WithBaseURL(url string) Option

func WithCustomHeaders

func WithCustomHeaders(headers map[string]string) Option

func WithDefaultHandler

func WithDefaultHandler(handler func(string) (Flag, error)) Option

func WithEnvironmentRefreshInterval

func WithEnvironmentRefreshInterval(interval time.Duration) Option

func WithErrorHandler

func WithErrorHandler(handler func(handler *FlagsmithAPIError)) Option

WithErrorHandler provides a way to handle errors that occur during update of an environment.

func WithEvents added in v5.3.0

func WithEvents(ctx context.Context) Option

WithEvents enables experimentation events. Cancelling ctx performs the shutdown flush, bounded by the request timeout. Not compatible with WithOfflineMode. See the README's Experimentation section for delivery and failure handling.

func WithEventsBaseURL added in v5.3.0

func WithEventsBaseURL(url string) Option

WithEventsBaseURL sets the events API base URL. A trailing slash is added if missing. Defaults to DefaultEventsBaseURL.

func WithEventsFlushInterval added in v5.3.0

func WithEventsFlushInterval(interval time.Duration) Option

WithEventsFlushInterval sets how often buffered events are sent; 0 disables the timer. Defaults to DefaultEventsFlushInterval.

func WithEventsMaxBufferSize added in v5.3.0

func WithEventsMaxBufferSize(size int) Option

WithEventsMaxBufferSize sets the buffer size that triggers a send; beyond it the oldest events are dropped. Defaults to DefaultEventsMaxBufferSize.

func WithEventsRetryBackoff added in v5.3.0

func WithEventsRetryBackoff(backoff time.Duration) Option

WithEventsRetryBackoff sets the backoff before the first retry of a failed batch. It doubles, up to 10 seconds, with full jitter. Defaults to DefaultEventsRetryBackoff.

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) Option

func WithLocalEvaluation

func WithLocalEvaluation(ctx context.Context) Option

WithLocalEvaluation enables local evaluation of the Feature flags.

The goroutine responsible for asynchronously updating the environment makes use of the context provided here, which means that if it expires the background process will exit.

func WithLogger

func WithLogger(logger Logger) Option

Allows the client to use any logger that implements the `Logger` interface.

func WithOfflineHandler

func WithOfflineHandler(handler OfflineHandler) Option

WithOfflineHandler returns an Option function that sets the offline handler.

func WithOfflineMode

func WithOfflineMode() Option

WithOfflineMode returns an Option function that enables the offline mode. NOTE: before using this option, you should set the offline handler.

func WithPolling

func WithPolling() Option

WithPolling makes it so that the client will poll for updates even when WithRealtime is used.

func WithProxy

func WithProxy(proxyURL string) Option

WithProxy returns an Option function that sets the proxy(to be used by internal resty client). The proxyURL argument is a string representing the URL of the proxy server to use, e.g. "http://proxy.example.com:8080".

func WithRealtime

func WithRealtime() Option

WithRealtime returns an Option function that enables real-time updates for the Client. NOTE: Before enabling real-time updates, ensure that local evaluation is enabled.

func WithRealtimeBaseURL

func WithRealtimeBaseURL(url string) Option

WithRealtimeBaseURL returns an Option function for configuring the real-time base URL of the Client.

func WithRemoteEvaluation

func WithRemoteEvaluation() Option

func WithRequestTimeout

func WithRequestTimeout(timeout time.Duration) Option

func WithRestyClient

func WithRestyClient(restyClient *resty.Client) Option

func WithRetries

func WithRetries(count int, waitTime time.Duration) Option

func WithSlogLogger

func WithSlogLogger(logger *slog.Logger) Option

WithSlogLogger allows the client to use a slog.Logger for logging.

type Trait

type Trait = trait.Trait

type TraitEvaluationContext

type TraitEvaluationContext struct {
	Transient *bool       `json:"transient,omitempty"`
	Value     interface{} `json:"value"`
}

TraitEvaluationContext represents a single trait value used within an IdentityEvaluationContext. A Transient trait will not be persisted.

func NewTraitEvaluationContext

func NewTraitEvaluationContext(value interface{}, transient bool) TraitEvaluationContext

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL