flaglite

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2026 License: MIT Imports: 10 Imported by: 0

README

FlagLite Go SDK

The official Go SDK for FlagLite, a simple and fast feature flag service.

Go Reference Go Report Card

Features

  • 🚀 Simple API - One method to check flags: Enabled()
  • Fast - Built-in caching with configurable TTL (default 30s)
  • 🔒 Fail-closed - Returns false on any error (safe defaults)
  • 🧵 Thread-safe - Safe for concurrent use
  • 🎯 User targeting - Sticky bucketing for percentage rollouts
  • ⚙️ Configurable - Functional options pattern for clean configuration

Installation

go get github.com/faiscadev/flaglite-go

Quick Start

package main

import "github.com/faiscadev/flaglite-go"

func main() {
    // Create client (reads FLAGLITE_API_KEY from environment)
    client := flaglite.New()

    // Check if a feature is enabled
    if client.Enabled("new-checkout") {
        showNewCheckout()
    } else {
        showOldCheckout()
    }
}

Configuration

API Key

Set your environment API key via environment variable:

export FLAGLITE_API_KEY=ffl_env_xxxxx

Or pass it directly:

client := flaglite.New(flaglite.WithAPIKey("ffl_env_xxxxx"))
Options
client := flaglite.New(
    // Custom API key (overrides FLAGLITE_API_KEY env var)
    flaglite.WithAPIKey("ffl_env_xxxxx"),

    // Custom cache TTL (default: 30s, set to 0 to disable)
    flaglite.WithCacheTTL(1 * time.Minute),

    // Custom HTTP timeout (default: 5s)
    flaglite.WithTimeout(3 * time.Second),

    // Custom base URL (for self-hosted or testing)
    flaglite.WithBaseURL("https://my-flaglite.example.com/v1"),

    // Custom HTTP client
    flaglite.WithHTTPClient(myHTTPClient),
)

Usage

Basic Flag Check
if client.Enabled("dark-mode") {
    enableDarkMode()
}
Percentage Rollouts with User ID

For percentage rollouts, provide a user ID to ensure consistent behavior (sticky bucketing):

// Same user always gets the same result for the same flag
if client.Enabled("new-feature", flaglite.WithUserID(user.ID)) {
    showNewFeature()
}
Error Handling

The default Enabled() method silently fails closed (returns false). If you need to handle errors:

enabled, err := client.EnabledWithError("my-flag")
if err != nil {
    log.Printf("Flag evaluation failed: %v", err)
    // Handle gracefully - enabled is false
}
Context Support

For deadline/cancellation control:

ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()

enabled, err := client.EnabledWithContext(ctx, "my-flag")
Cache Management
// Clear all cached values (e.g., after a deployment)
client.ClearCache()

Best Practices

1. Create a Single Client

Create one client at startup and reuse it:

var flags *flaglite.Client

func init() {
    flags = flaglite.New()
}

func handler(w http.ResponseWriter, r *http.Request) {
    if flags.Enabled("feature-x") {
        // ...
    }
}
2. Use User IDs for Rollouts

Always provide a user ID for percentage rollouts to ensure consistent behavior:

// Good - consistent experience per user
if flags.Enabled("new-ui", flaglite.WithUserID(userID)) { ... }

// Avoid - random result each time
if flags.Enabled("new-ui") { ... }
3. Handle Missing Flags Gracefully

The SDK returns false for non-existent flags. Design your code to handle this:

// Feature is off by default, on when flag is enabled
if flags.Enabled("experimental-feature") {
    useExperimentalPath()
} else {
    useStablePath() // This is the default/safe path
}
4. Configure Appropriate Cache TTL

Balance freshness vs. API load:

// Real-time flags (more API calls)
flaglite.WithCacheTTL(5 * time.Second)

// Less critical flags (fewer API calls)
flaglite.WithCacheTTL(5 * time.Minute)

API Reference

Client Methods
Method Description
Enabled(key string, opts ...EvalOption) bool Check if flag is enabled (fails closed)
EnabledWithError(key string, opts ...EvalOption) (bool, error) Check flag with error returned
EnabledWithContext(ctx context.Context, key string, opts ...EvalOption) (bool, error) Check flag with context support
ClearCache() Clear all cached flag values
Client Options
Option Description
WithAPIKey(key string) Set the API key
WithBaseURL(url string) Set custom base URL
WithCacheTTL(ttl time.Duration) Set cache TTL (0 to disable)
WithTimeout(timeout time.Duration) Set HTTP timeout
WithHTTPClient(client *http.Client) Use custom HTTP client
Evaluation Options
Option Description
WithUserID(userID string) Set user ID for percentage rollouts

Environment Variables

Variable Description
FLAGLITE_API_KEY Default API key (environment key)

Thread Safety

The Client is safe for concurrent use. You can call Enabled() from multiple goroutines simultaneously.

Error Handling

The SDK follows a fail-closed philosophy:

  • Network errors → returns false
  • Invalid API key → returns false
  • Flag not found → returns false
  • Rate limited → returns false
  • Malformed response → returns false

Use EnabledWithError() if you need to distinguish between errors and disabled flags.

CI/CD

This package uses automated CI/CD:

  • CI: Runs on every push/PR - linting (golangci-lint), format check, tests across Go 1.22/1.23/1.24
  • Release: Tag with v* (e.g., git tag v1.0.0 && git push --tags) to create a GitHub release

pkg.go.dev automatically indexes new releases from GitHub tags - no secrets required.

License

MIT License - see LICENSE for details.

Documentation

Overview

Package flaglite provides a Go SDK for the FlagLite feature flag service.

The SDK supports:

  • Simple boolean flag evaluation
  • Percentage rollouts with user ID targeting
  • Thread-safe caching with configurable TTL
  • Fail-closed behavior (returns false on errors)

Basic usage:

client := flaglite.New() // Uses FLAGLITE_API_KEY env var

if client.Enabled("new-checkout") {
    showNewCheckout()
}

With user targeting for percentage rollouts:

if client.Enabled("new-checkout", flaglite.WithUserID("user-123")) {
    showNewCheckout()
}

Index

Constants

View Source
const (
	// DefaultBaseURL is the production FlagLite API endpoint.
	DefaultBaseURL = "https://api.flaglite.dev/v1"

	// DefaultCacheTTL is the default cache duration for flag evaluations.
	DefaultCacheTTL = 30 * time.Second

	// DefaultTimeout is the default HTTP request timeout.
	DefaultTimeout = 5 * time.Second

	// EnvAPIKey is the environment variable name for the API key.
	EnvAPIKey = "FLAGLITE_API_KEY"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client is the FlagLite SDK client for evaluating feature flags. It is safe for concurrent use by multiple goroutines.

func New

func New(opts ...ClientOption) *Client

New creates a new FlagLite client.

By default, it reads the API key from the FLAGLITE_API_KEY environment variable. Use WithAPIKey to override this.

Example:

client := flaglite.New()
client := flaglite.New(flaglite.WithAPIKey("ffl_env_..."))
client := flaglite.New(flaglite.WithCacheTTL(1 * time.Minute))

func (*Client) ClearCache

func (c *Client) ClearCache()

ClearCache removes all cached flag evaluations. This can be useful when you know flags have changed.

func (*Client) Enabled

func (c *Client) Enabled(key string, opts ...EvalOption) bool

Enabled checks if a feature flag is enabled.

This method is thread-safe and uses caching to minimize API calls. On any error (network, invalid key, etc.), it returns false (fail-closed).

Example:

if client.Enabled("new-checkout") {
    showNewCheckout()
}

// With user targeting for percentage rollouts
if client.Enabled("new-checkout", flaglite.WithUserID("user-123")) {
    showNewCheckout()
}

func (*Client) EnabledWithContext

func (c *Client) EnabledWithContext(ctx context.Context, key string, opts ...EvalOption) (bool, error)

EnabledWithContext checks if a feature flag is enabled with context support.

The context can be used for cancellation and deadline control.

Example:

ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
defer cancel()
enabled, err := client.EnabledWithContext(ctx, "new-checkout")

func (*Client) EnabledWithError

func (c *Client) EnabledWithError(key string, opts ...EvalOption) (bool, error)

EnabledWithError checks if a feature flag is enabled and returns any error.

Unlike Enabled(), this method returns the error for debugging purposes. On error, the first return value is always false (fail-closed).

Example:

enabled, err := client.EnabledWithError("new-checkout")
if err != nil {
    log.Printf("flag evaluation failed: %v", err)
}

type ClientOption

type ClientOption func(*Client)

ClientOption configures a Client.

func WithAPIKey

func WithAPIKey(key string) ClientOption

WithAPIKey sets the API key for the client.

func WithBaseURL

func WithBaseURL(baseURL string) ClientOption

WithBaseURL sets a custom base URL (useful for testing or self-hosted).

func WithCacheTTL

func WithCacheTTL(ttl time.Duration) ClientOption

WithCacheTTL sets the cache TTL duration. Set to 0 to disable caching.

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) ClientOption

WithHTTPClient sets a custom HTTP client.

func WithTimeout

func WithTimeout(timeout time.Duration) ClientOption

WithTimeout sets the HTTP request timeout.

type EvalOption

type EvalOption func(*evalConfig)

EvalOption configures a single flag evaluation.

func WithUserID

func WithUserID(userID string) EvalOption

WithUserID specifies the user ID for percentage rollout targeting. This enables sticky bucketing - the same user always gets the same result.

Jump to

Keyboard shortcuts

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