Documentation
¶
Overview ¶
Package flagmint is the Go SDK for the Flagmint feature flag service.
Quick start ¶
client, err := flagmint.NewClient("your-api-key",
flagmint.WithContext(flagmint.EvaluationContext{
Kind: "user",
Key: "user-123",
}),
)
if err != nil {
log.Fatal(err)
}
defer client.Close()
// Block until flags are available (or timeout).
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := client.Ready(ctx); err != nil {
log.Fatal(err)
}
enabled := client.BoolFlag("my-feature", false)
Architecture ¶
The SDK maintains a persistent connection to the Flagmint backend (WebSocket by default, with HTTP long-polling as a fallback). Flags are evaluated server-side and streamed to the client in real time. An optional local evaluator (Ticket 5) can evaluate flags without a round-trip when offline.
Package flagmint provides the Go SDK for the Flagmint feature flag service.
Example (BoolFlag) ¶
Example_boolFlag shows how to evaluate a boolean feature flag with a default fallback value.
package main
import (
"fmt"
"log"
flagmint "github.com/flagmint/flagmint-go"
)
func main() {
client, err := flagmint.NewClient("fm_sdk_your_api_key",
flagmint.WithDeferInit(),
)
if err != nil {
log.Fatal(err)
}
defer client.Close() //nolint:errcheck
// BoolFlag returns the flag value, or fallback (false) if the flag is
// absent or not a boolean.
if client.BoolFlag("new-checkout", false) {
fmt.Println("new checkout experience is active")
} else {
fmt.Println("using standard checkout")
}
}
Output: using standard checkout
Example (NewClient) ¶
Example_newClient demonstrates creating a client, waiting for it to be ready, and reading a boolean flag value.
package main
import (
"context"
"fmt"
"log"
"time"
flagmint "github.com/flagmint/flagmint-go"
)
func main() {
client, err := flagmint.NewClient("fm_sdk_your_api_key",
flagmint.WithContext(flagmint.EvaluationContext{
Kind: "user",
Key: "user-123",
Attributes: map[string]any{
"country": "DE",
"plan": "pro",
},
}),
flagmint.WithDeferInit(),
)
if err != nil {
log.Fatal(err)
}
defer client.Close() //nolint:errcheck
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// Ready blocks until the transport is connected and flags are available,
// or until ctx is cancelled. In a real application, remove WithDeferInit()
// to connect automatically on NewClient.
_ = client.Ready(ctx)
enabled := client.BoolFlag("dark-mode", false)
fmt.Println("dark-mode:", enabled)
}
Output:
Example (Subscribe) ¶
Example_subscribe shows how to register a callback that fires whenever the flag set changes.
package main
import (
"fmt"
"log"
flagmint "github.com/flagmint/flagmint-go"
)
func main() {
client, err := flagmint.NewClient("fm_sdk_your_api_key",
flagmint.WithDeferInit(),
)
if err != nil {
log.Fatal(err)
}
defer client.Close() //nolint:errcheck
// Subscribe fires immediately with the current state, then again on every
// update. The returned function removes the subscription.
unsub := client.Subscribe(func(flags flagmint.FeatureFlags) {
fmt.Println("flags updated, count:", flags.Len())
})
defer unsub()
}
Output: flags updated, count: 0
Example (WithLocalEvaluation) ¶
Example_withLocalEvaluation demonstrates setting up local evaluation with a manually supplied FlagConfig. In production the configs come from the /evaluator/config endpoint.
package main
import (
"fmt"
"log"
flagmint "github.com/flagmint/flagmint-go"
"github.com/flagmint/flagmint-go/evaluate"
)
func main() {
client, err := flagmint.NewClient("fm_sdk_your_api_key",
flagmint.WithLocalEvaluation(),
flagmint.WithContext(flagmint.EvaluationContext{
Kind: "user",
Key: "user-456",
Attributes: map[string]any{
"plan": "pro",
},
}),
flagmint.WithDeferInit(),
)
if err != nil {
log.Fatal(err)
}
defer client.Close() //nolint:errcheck
darkMode := &evaluate.FlagConfig{
Key: "dark-mode",
Type: evaluate.FlagTypeBoolean,
IsActive: true,
DefaultValue: false,
Variations: []evaluate.Variation{
{ID: "v-off", Value: false},
{ID: "v-on", Value: true},
},
TargetingRules: []evaluate.TargetingRule{
{
ID: "rule-pro",
Kind: "custom",
LogicalOp: evaluate.LogicalAND,
Conditions: []evaluate.Condition{
{
Attribute: "plan",
Operator: evaluate.OpEquals,
Value: "pro",
},
},
VariationID: strPtr("v-on"),
},
},
}
darkMode.HydrateVariations()
client.SetFlagConfigs(map[string]*evaluate.FlagConfig{
"dark-mode": darkMode,
})
// Evaluation is fully local — no network round-trip.
enabled := client.BoolFlag("dark-mode", false)
fmt.Println("dark-mode:", enabled)
}
func strPtr(s string) *string { return &s }
Output: dark-mode: true
Index ¶
- Constants
- Variables
- type CacheAdapter
- type ContextEntity
- type EvaluationContext
- type FeatureFlags
- func (f FeatureFlags) Bool(key string, fallback bool) bool
- func (f FeatureFlags) Clone() FeatureFlags
- func (f FeatureFlags) Float64(key string, fallback float64) float64
- func (f FeatureFlags) Get(key string) (any, bool)
- func (f FeatureFlags) Has(key string) bool
- func (f FeatureFlags) JSON(key string, target any) error
- func (f FeatureFlags) Len() int
- func (f FeatureFlags) MarshalJSON() ([]byte, error)
- func (f FeatureFlags) String(key string, fallback string) string
- func (f FeatureFlags) ToMap() map[string]any
- func (f *FeatureFlags) UnmarshalJSON(data []byte) error
- type FlagClient
- func (c *FlagClient) Bool(key string, fallback bool) bool
- func (c *FlagClient) BoolFlag(key string, fallback bool) bool
- func (c *FlagClient) Close() error
- func (c *FlagClient) Float64(key string, fallback float64) float64
- func (c *FlagClient) GetFlag(key string, fallback any) any
- func (c *FlagClient) GetFlags() FeatureFlags
- func (c *FlagClient) Initialize(ctx context.Context) error
- func (c *FlagClient) JSON(key string, target any) error
- func (c *FlagClient) JSONFlag(key string, fallback map[string]any) map[string]any
- func (c *FlagClient) NumberFlag(key string, fallback float64) float64
- func (c *FlagClient) Ready(ctx context.Context) error
- func (c *FlagClient) SetContext(ctx EvaluationContext)
- func (c *FlagClient) SetFlagConfigs(configs map[string]*evaluate.FlagConfig)
- func (c *FlagClient) String(key string, fallback string) string
- func (c *FlagClient) StringFlag(key string, fallback string) string
- func (c *FlagClient) Subscribe(fn func(FeatureFlags)) func()
- func (c *FlagClient) UpdateContext(ctx EvaluationContext) error
- type FlagType
- type Option
- func WithCache(enabled bool) Option
- func WithCacheAdapter(adapter CacheAdapter) Option
- func WithContext(ctx EvaluationContext) Option
- func WithDeferInit() Option
- func WithEndpoints(rest, ws string) Option
- func WithLocalEvaluation() Option
- func WithLogger(l *slog.Logger) Option
- func WithOnError(fn func(error)) Option
- func WithTransportMode(mode TransportMode) Option
- type TransportMode
Examples ¶
Constants ¶
const ( EnvFlagmintRestEndpoint = "FLAGMINT_REST_ENDPOINT" EnvFlagmintWSEndpoint = "FLAGMINT_WS_ENDPOINT" EnvFlagmintEnv = "FLAGMINT_ENV" )
Environment variable names
const DefaultCacheTTL = 24 * time.Hour
DefaultCacheTTL is the default time-to-live for cached flags. Matches the JS SDK's DEFAULT_CACHE_TTL (24 * 60 * 60 * 1000 ms).
Variables ¶
var ErrFlagNotFound = errors.New("flagmint: flag not found")
ErrFlagNotFound is returned by FeatureFlags.JSON when the requested key does not exist in the flag set.
Functions ¶
This section is empty.
Types ¶
type CacheAdapter ¶
type CacheAdapter interface {
// LoadFlags returns cached flags for the given API key, or nil if
// no valid (non-expired) cache entry exists. Errors indicate storage
// failure, not cache misses.
LoadFlags(apiKey string) (*FeatureFlags, error)
// SaveFlags persists flags for the given API key. Called on every
// flag update — implementations should be fast (async write is fine).
SaveFlags(apiKey string, flags FeatureFlags) error
// LoadContext returns the cached evaluation context, or nil if none exists.
// Context entries have no TTL — they persist until overwritten.
LoadContext(apiKey string) (*EvaluationContext, error)
// SaveContext persists the evaluation context. Unlike flags, the context
// has no TTL and remains valid until explicitly overwritten.
SaveContext(apiKey string, ctx *EvaluationContext) error
}
CacheAdapter provides persistence for flags and evaluation context across client restarts. Implementations must be safe for concurrent use.
type ContextEntity ¶
type ContextEntity struct {
Kind string `json:"kind,omitempty"`
Key string `json:"key"`
Attributes map[string]any `json:"attributes,omitempty"`
}
ContextEntity represents a single entity within a multi-kind context.
func (ContextEntity) MarshalJSON ¶
func (ce ContextEntity) MarshalJSON() ([]byte, error)
MarshalJSON flattens attributes to the top level for API compatibility.
type EvaluationContext ¶
type EvaluationContext struct {
Kind string `json:"kind"` // "user", "organization", "multi"
Key string `json:"key"`
Attributes map[string]any `json:"attributes,omitempty"`
User *ContextEntity `json:"user,omitempty"` // for kind="multi"
Organization *ContextEntity `json:"organization,omitempty"` // for kind="multi"
}
EvaluationContext is the user/org context sent to the server for evaluation. Mirrors EvaluationContextT from the JS SDK.
func (EvaluationContext) Flatten ¶
func (e EvaluationContext) Flatten() map[string]any
Flatten returns a flat map of all attributes for the context, suitable for rule evaluation. For a "multi" kind context the user and organization sub-contexts are merged under "user.<key>" and "organization.<key>" prefixes.
func (EvaluationContext) MarshalJSON ¶
func (ec EvaluationContext) MarshalJSON() ([]byte, error)
MarshalJSON flattens attributes to the top level for API compatibility.
type FeatureFlags ¶
type FeatureFlags struct {
// contains filtered or unexported fields
}
FeatureFlags holds the evaluated feature flags returned by the server. Use the type-safe getter methods (Bool, String, Float64, JSON) to retrieve individual flag values. The zero value is valid and returns fallbacks for all keys.
func NewFeatureFlags ¶
func NewFeatureFlags(values map[string]any) FeatureFlags
NewFeatureFlags wraps the raw server payload in a type-safe FeatureFlags.
func (FeatureFlags) Bool ¶
func (f FeatureFlags) Bool(key string, fallback bool) bool
Bool retrieves a boolean flag value. Returns fallback when the key is absent or the stored value is not a bool.
func (FeatureFlags) Clone ¶
func (f FeatureFlags) Clone() FeatureFlags
Clone returns a shallow copy of the flag set. The copy has its own map so the caller cannot mutate the original values.
func (FeatureFlags) Float64 ¶
func (f FeatureFlags) Float64(key string, fallback float64) float64
Float64 retrieves a numeric flag value. Returns fallback when the key is absent or the stored value is not a float64.
func (FeatureFlags) Get ¶
func (f FeatureFlags) Get(key string) (any, bool)
Get returns the raw value for a flag key and whether it was found.
func (FeatureFlags) Has ¶
func (f FeatureFlags) Has(key string) bool
Has reports whether a flag with the given key exists in the set.
func (FeatureFlags) JSON ¶
func (f FeatureFlags) JSON(key string, target any) error
JSON unmarshals a complex flag configuration into target (must be a pointer). Returns ErrFlagNotFound when the key is absent, or a marshalling error when the stored value cannot be encoded/decoded into target.
func (FeatureFlags) Len ¶
func (f FeatureFlags) Len() int
Len returns the number of flags in the set.
func (FeatureFlags) MarshalJSON ¶
func (f FeatureFlags) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler so that FeatureFlags can be serialised directly by external cache adapters.
func (FeatureFlags) String ¶
func (f FeatureFlags) String(key string, fallback string) string
String retrieves a string flag value. Returns fallback when the key is absent or the stored value is not a string.
func (FeatureFlags) ToMap ¶
func (f FeatureFlags) ToMap() map[string]any
ToMap returns a shallow copy of all flag values as a plain map. This is useful for external cache adapters that need to serialise flags.
func (*FeatureFlags) UnmarshalJSON ¶
func (f *FeatureFlags) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler so that FeatureFlags can be deserialised by external cache adapters.
type FlagClient ¶
type FlagClient struct {
// contains filtered or unexported fields
}
FlagClient is the main entry point for interacting with the Flagmint feature flag service. Create one via NewClient. Safe for concurrent use by multiple goroutines.
func NewClient ¶
func NewClient(apiKey string, opts ...Option) (*FlagClient, error)
NewClient creates a new FlagClient. Returns an error only for invalid configuration (missing API key, etc). Transport connection happens asynchronously; call FlagClient.Ready to block until flags are available.
client, err := flagmint.NewClient("your-api-key",
flagmint.WithContext(flagmint.EvaluationContext{Kind: "user", Key: "u123"}),
)
func (*FlagClient) Bool ¶
func (c *FlagClient) Bool(key string, fallback bool) bool
Bool returns the boolean value of flag key, or fallback if the flag is absent or not a bool. When local evaluation is enabled, delegates to FlagClient.GetFlag.
func (*FlagClient) BoolFlag ¶
func (c *FlagClient) BoolFlag(key string, fallback bool) bool
BoolFlag is a typed convenience method. Returns fallback if the flag doesn't exist or isn't a bool. When local evaluation is enabled, the flag is evaluated locally against the configured evaluate.FlagConfig rules.
func (*FlagClient) Close ¶
func (c *FlagClient) Close() error
Close shuts down the client, cancels the internal context, closes the transport, and releases all subscriber registrations. Safe to call more than once.
func (*FlagClient) Float64 ¶
func (c *FlagClient) Float64(key string, fallback float64) float64
Float64 returns the numeric value of flag key, or fallback if the flag is absent or not a float64. When local evaluation is enabled, delegates to FlagClient.GetFlag.
func (*FlagClient) GetFlag ¶
func (c *FlagClient) GetFlag(key string, fallback any) any
GetFlag returns the value for a single flag key, or fallback if not found. When local evaluation is enabled (see WithLocalEvaluation) the flag is evaluated against the full FlagConfig stored via FlagClient.SetFlagConfigs.
func (*FlagClient) GetFlags ¶
func (c *FlagClient) GetFlags() FeatureFlags
GetFlags returns a shallow copy of all current flag values. The caller cannot mutate the client's internal flag state.
func (*FlagClient) Initialize ¶
func (c *FlagClient) Initialize(ctx context.Context) error
Initialize connects the underlying transport to the Flagmint backend and blocks until flags are available or ctx is cancelled. It is called automatically by NewClient unless WithDeferInit was used. Calling Initialize is equivalent to calling Ready(ctx).
func (*FlagClient) JSON ¶
func (c *FlagClient) JSON(key string, target any) error
JSON unmarshals a JSON flag configuration into target (must be a pointer). Returns ErrFlagNotFound when the key is absent.
func (*FlagClient) JSONFlag ¶
JSONFlag is a typed convenience method. Returns the flag as map[string]any, or fallback if the flag doesn't exist or isn't a JSON object.
func (*FlagClient) NumberFlag ¶
func (c *FlagClient) NumberFlag(key string, fallback float64) float64
NumberFlag is a typed convenience method. Flags are float64 internally. Returns fallback if the flag doesn't exist or isn't a float64. When local evaluation is enabled, the flag is evaluated locally against the configured evaluate.FlagConfig rules.
func (*FlagClient) Ready ¶
func (c *FlagClient) Ready(ctx context.Context) error
Ready blocks until the client has flags available (from cache or server) or the provided context is cancelled/times out.
If WithDeferInit was used, Ready triggers the first connection. Subsequent calls return the original result immediately.
Returns nil if flags are available (even if from cache in degraded mode). Returns an error if initialisation failed and no cached flags exist, or if the provided context or internal context is cancelled.
func (*FlagClient) SetContext ¶
func (c *FlagClient) SetContext(ctx EvaluationContext)
SetContext updates the evaluation context. Deprecated: use UpdateContext.
func (*FlagClient) SetFlagConfigs ¶
func (c *FlagClient) SetFlagConfigs(configs map[string]*evaluate.FlagConfig)
SetFlagConfigs replaces the local flag configuration used for local evaluation. Pass a map of flag key → *evaluate.FlagConfig. Each config's evaluate.FlagConfig.HydrateVariations must have been called before passing it here if it was not already hydrated. This method is a no-op when WithLocalEvaluation was not set.
func (*FlagClient) String ¶
func (c *FlagClient) String(key string, fallback string) string
String returns the string value of flag key, or fallback if the flag is absent or not a string. When local evaluation is enabled, delegates to FlagClient.GetFlag.
func (*FlagClient) StringFlag ¶
func (c *FlagClient) StringFlag(key string, fallback string) string
StringFlag is a typed convenience method. Returns fallback if the flag doesn't exist or isn't a string. When local evaluation is enabled, the flag is evaluated locally against the configured evaluate.FlagConfig rules.
func (*FlagClient) Subscribe ¶
func (c *FlagClient) Subscribe(fn func(FeatureFlags)) func()
Subscribe registers a callback that fires whenever flags change. The callback is also invoked immediately with the current flag state. Returns an unsubscribe function; calling it removes the subscription. Safe to call from any goroutine.
Callbacks are invoked synchronously and should be fast and non-blocking. If slow work is needed, dispatch to a separate goroutine inside the callback.
func (*FlagClient) UpdateContext ¶
func (c *FlagClient) UpdateContext(ctx EvaluationContext) error
UpdateContext merges the provided evaluation context with the existing one, persists it to the cache if caching is enabled, and triggers a flag re-evaluation. Thread-safe.
type Option ¶
type Option func(*clientConfig)
Option configures the FlagClient. Use With* functions to create options.
func WithCacheAdapter ¶
func WithCacheAdapter(adapter CacheAdapter) Option
WithCacheAdapter sets a custom cache adapter. Implementations must be safe for concurrent use. Enables caching automatically.
func WithContext ¶
func WithContext(ctx EvaluationContext) Option
WithContext sets the default evaluation context for the client.
func WithDeferInit ¶
func WithDeferInit() Option
WithDeferInit prevents the client from connecting immediately on creation. Call FlagClient.Initialize manually when ready.
func WithEndpoints ¶
WithEndpoints overrides the default REST and WebSocket API endpoints.
func WithLocalEvaluation ¶
func WithLocalEvaluation() Option
WithLocalEvaluation enables local flag evaluation mode. When active, the client evaluates flags locally using FlagConfig objects instead of consuming pre-evaluated values from the server. This eliminates network round-trips for each flag check and keeps user context on-premise.
In local evaluation mode, call FlagClient.SetFlagConfigs to supply the flag rule configuration. The transport integration (auto-fetching configs from /evaluator/config) is tracked separately.
func WithLogger ¶
WithLogger sets the structured logger used by the client.
func WithOnError ¶
WithOnError registers a callback invoked when the client encounters a non-fatal error (e.g., a failed flag refresh).
func WithTransportMode ¶
func WithTransportMode(mode TransportMode) Option
WithTransportMode sets the transport mechanism.
type TransportMode ¶
type TransportMode string
TransportMode controls the transport mechanism used by the client.
const ( // TransportAuto selects WebSocket when available, falling back to long-polling. TransportAuto TransportMode = "auto" // TransportWebSocket forces the WebSocket transport. TransportWebSocket TransportMode = "websocket" // TransportLongPolling forces the HTTP long-polling transport. TransportLongPolling TransportMode = "long-polling" )
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package evaluate provides local flag evaluation logic for the Flagmint Go SDK.
|
Package evaluate provides local flag evaluation logic for the Flagmint Go SDK. |
|
examples
|
|
|
basic
command
Package main demonstrates basic usage of the Flagmint Go SDK.
|
Package main demonstrates basic usage of the Flagmint Go SDK. |
|
local-eval
command
Package main demonstrates local flag evaluation with the Flagmint Go SDK.
|
Package main demonstrates local flag evaluation with the Flagmint Go SDK. |
|
internal
|
|
|
backoff
Package backoff provides exponential back-off with jitter.
|
Package backoff provides exponential back-off with jitter. |
|
syncutil
Package syncutil provides small synchronisation helpers used internally.
|
Package syncutil provides small synchronisation helpers used internally. |
|
Package transport defines the Transport interface and its implementations.
|
Package transport defines the Transport interface and its implementations. |