### Install GrowthBook Go SDK Source: https://github.com/growthbook/growthbook-golang/blob/main/README.md Use `go get` to install the GrowthBook Go SDK. Ensure you have Go version 1.21 or higher. ```bash go get github.com/growthbook/growthbook-golang ``` -------------------------------- ### StickyBucketAssignmentDoc Example Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/sticky-bucketing.md Illustrates how to create and populate a StickyBucketAssignmentDoc. This example shows assignments for multiple experiments and different bucket versions. ```go doc := &gb.StickyBucketAssignmentDoc{ AttributeName: "id", AttributeValue: "user-456", Assignments: map[string]string{ "experiment-1__0": "control", // v0: assigned to control "experiment-1__1": "treatment", // v1: reassigned to treatment "experiment-2__0": "variant-b", // Different experiment }, } ``` -------------------------------- ### Example Custom Plugin Implementation Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/plugins.md Provides a concrete implementation of the `Plugin` interface. This example demonstrates how to initialize a plugin, log experiment views, and log feature evaluations using the client's logger. ```go type CustomPlugin struct { client *Client logger *slog.Logger } func (p *CustomPlugin) Init(client *Client) error { p.client = client p.logger = client.Logger() return nil } func (p *CustomPlugin) OnExperimentViewed(ctx context.Context, exp *Experiment, result *ExperimentResult) { p.logger.Info("Experiment viewed", "key", exp.Key, "variation_id", result.VariationId, ) } func (p *CustomPlugin) OnFeatureEvaluated(ctx context.Context, key string, result *FeatureResult) { p.logger.Debug("Feature evaluated", "key", key, "source", result.Source, ) } func (p *CustomPlugin) Close() error { return nil } ``` -------------------------------- ### Example Attributes Initialization Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Example of creating and using Attributes to initialize a Growthbook client. Pass custom user attributes like ID, email, and role for targeted feature evaluation. ```go attrs := gb.Attributes{ "id": "user-123", "email": "user@example.com", "org": "acme", "role": "admin", "country": "US", "joined": time.Now().AddDate(-1, 0, 0), // 1 year ago } client, _ := gb.NewClient(ctx, gb.WithAttributes(attrs)) ``` -------------------------------- ### Creating and Configuring a New Experiment Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Example of creating a new experiment using `NewExperiment` and then setting its variations and weights. ```go exp := gb.NewExperiment("color-test") exp.Variations = []gb.FeatureValue{"red", "blue"} exp.Weights = []float64{0.5, 0.5} ``` -------------------------------- ### Initialize GrowthBookTrackingPlugin Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/plugins.md Example of creating a new GrowthBookTrackingPlugin and initializing a GrowthBook client with it. ```go plugin := gb.NewGrowthBookTrackingPlugin(gb.TrackingPluginConfig{ IngestorHost: "https://us1.gb-ingest.com", }) client, _ := gb.NewClient(ctx, gb.WithPlugins(plugin)) ``` -------------------------------- ### Custom Database Sticky Bucket Service Implementation Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/sticky-bucketing.md Implement a custom sticky bucket service backed by a database. This example shows how to define the service struct and implement methods for getting and saving assignments. ```go type DatabaseStickyBucketService struct { db *sql.DB mu sync.RWMutex } func (s *DatabaseStickyBucketService) GetAssignments(attributeName, attributeValue string) (*gb.StickyBucketAssignmentDoc, error) { var doc gb.StickyBucketAssignmentDoc // Query database row := s.db.QueryRow( "SELECT attribute_name, attribute_value, assignments FROM sticky_buckets WHERE attribute_name = $1 AND attribute_value = $2", attributeName, attributeValue, ) var assignmentsJSON string err := row.Scan(&doc.AttributeName, &doc.AttributeValue, &assignmentsJSON) if err == sql.ErrNoRows { return nil, nil // Not found is not an error } if err != nil { return nil, err } // Deserialize assignments if err := json.Unmarshal([]byte(assignmentsJSON), &doc.Assignments); err != nil { return nil, err } return &doc, nil } func (s *DatabaseStickyBucketService) SaveAssignments(doc *gb.StickyBucketAssignmentDoc) error { assignmentsJSON, err := json.Marshal(doc.Assignments) if err != nil { return err } _, err = s.db.Exec( "INSERT INTO sticky_buckets (attribute_name, attribute_value, assignments) VALUES ($1, $2, $3) ON CONFLICT (attribute_name, attribute_value) DO UPDATE SET assignments = $3", doc.AttributeName, doc.AttributeValue, string(assignmentsJSON), ) return err } func (s *DatabaseStickyBucketService) GetAllAssignments(attributes map[string]string) (gb.StickyBucketAssignments, error) { result := make(gb.StickyBucketAssignments) for attrName, attrValue := range attributes { doc, err := s.GetAssignments(attrName, attrValue) if err != nil { return nil, err } if doc != nil { key := attrName + "||" + attrValue result[key] = doc } } return result, nil } ``` -------------------------------- ### Complete Example with All Options Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/SUMMARY.txt Demonstrates initializing the GrowthBook client with a comprehensive set of configuration options, including API host, client key, sticky bucketing, attributes, and callbacks. ```go import ( "context" "log" "net/http" "time" "github.com/growthbook/growthbook-golang/growthbook" ) // Custom logger implementation type MyLogger struct {} func (l *MyLogger) Log(level string, message string) { log.Printf("[%s] %s\n", level, message) } // Custom sticky bucket service type MyStickyBucketService struct {} func (s *MyStickyBucketService) GetAssignments(ctx context.Context, userId string) (growthbook.StickyBucketAssignments, error) { return nil, nil } func (s *MyStickyBucketService) SaveAssignments(ctx context.Context, userId string, assignments growthbook.StickyBucketAssignments) error { return nil } func (s *MyStickyBucketService) GetAllAssignments(ctx context.Context) (map[string]growthbook.StickyBucketAssignments, error) { return nil, nil } func (s *MyStickyBucketService) Destroy() error { return nil } // Experiment tracking callback func experimentCallback(ctx context.Context, result growthbook.ExperimentResult) { log.Printf("Experiment '%s' assigned to variation %d\n", result.Experiment.Key, result.Value) } // Feature usage tracking callback func featureUsageCallback(ctx context.Context, featureKey string, result growthbook.FeatureResult) { log.Printf("Feature '%s' evaluated to '%v'\n", featureKey, result.Value) } func main() { customHTTPClient := &http.Client{ Timeout: 5 * time.Second, } gb := growthbook.NewGrowthBook( growthbook.WithApiHost("https://api.growthbook.io"), growthbook.WithClientKey("your-client-key"), growthbook.WithDecryptionKey("your-decryption-key"), growthbook.WithStickyBucketService(&MyStickyBucketService{}), growthbook.WithStickyBucketAttributes(map[string]interface{}{"id": "user-123"}), growthbook.WithAttributes(map[string]interface{}{"loggedIn": true}), growthbook.WithUrl("https://example.com/page"), growthbook.WithQaMode(false), growthbook.WithForcedVariations(nil), growthbook.WithLogger(&MyLogger{}), growthbook.WithHttpClient(customHTTPClient), growthbook.WithExperimentCallback(experimentCallback), growthbook.WithFeatureUsageCallback(featureUsageCallback), growthbook.WithExtraData(map[string]interface{}{"request_id": "req-xyz"}), growthbook.WithGrowthBookTracking(), ) defer gb.Destroy() // Example usage: featureResult := gb.IsOn("some-feature") if featureResult.On { log.Println("Feature is ON") } else { log.Println("Feature is OFF") } experimentResult := gb.Run("my-experiment", []interface{}{"control", "treatment"}, "default") log.Printf("Experiment result: %v\n", experimentResult.Value) } ``` -------------------------------- ### Example Feature Map Initialization Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Shows how to initialize a FeatureMap with multiple feature flags. Each feature can have a default value and optional rules. ```go features := gb.FeatureMap{ "dark-mode": &gb.Feature{ DefaultValue: false, }, "new-checkout": &gb.Feature{ DefaultValue: nil, Rules: []gb.FeatureRule{...}, }, } ``` -------------------------------- ### Quick Start: Initialize and Use GrowthBook Client Source: https://github.com/growthbook/growthbook-golang/blob/main/README.md Initialize the GrowthBook client with a client key and SSE data source. Wait for data to load using `EnsureLoaded` and then create a child client with attributes to evaluate features. ```go import ( "context" "log" gb "github.com/growthbook/growthbook-golang" ) // Create a new client instance with a client key and // a data source that loads features in the background via SSE stream. // Pass the client's options to the NewClient function. client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), gb.WithSseDataSource(), ) defer client.Close() if err != nil { log.Fatal("Client initialization failed: ", err) } // The data source starts asynchronously. Use EnsureLoaded to // wait until the client data is initialized for the first time. if err := client.EnsureLoaded(context.Background()); err != nil { log.Fatal("Data loading failed: ", err) } // Create a child client with specific attributes. attrs := gb.Attributes{"id": 100, "user": "user1"} child, err := client.WithAttributes(attrs) if err != nil { log.Fatal("Child client creation failed: ", err) } // Evaluate a text feature buttonColor := child.EvalFeature(context.Background(), "buy-button-color") if buttonColor.Value == "blue" { // Perform actions for blue button } // Evaluate a boolean feature darkMode := child.EvalFeature(context.Background(), "dark-mode") if darkMode.On { // Enable dark mode } ``` -------------------------------- ### Handle Client Creation Errors Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/errors.md Check for errors during client initialization. These typically indicate configuration or setup issues. ```go client, err := gb.NewClient(ctx, opts...) if err != nil { // Handle configuration/setup errors log.Fatal(err) } ``` -------------------------------- ### StickyBucketAssignments Example Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/sticky-bucketing.md Demonstrates the structure of StickyBucketAssignments, showing how multiple StickyBucketAssignmentDoc instances are stored in a map. The key format is '{attributeName}||{attributeValue}'. ```go assignments := gb.StickyBucketAssignments{ "id||user-123": &gb.StickyBucketAssignmentDoc{ AttributeName: "id", AttributeValue: "user-123", Assignments: map[string]string{...}, }, "email||user@example.com": &gb.StickyBucketAssignmentDoc{...}, } ``` -------------------------------- ### Example TrackingPluginConfig Initialization Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/plugins.md Illustrates how to initialize the TrackingPluginConfig with custom settings for the ingestor host, batch size, batch timeout, and HTTP client. ```go config := gb.TrackingPluginConfig{ IngestorHost: "https://eu.gb-ingest.com", BatchSize: 50, BatchTimeout: 5 * time.Second, HTTPClient: &http.Client{Timeout: 10 * time.Second}, } ``` -------------------------------- ### Feature Evaluation Examples Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Demonstrates how to evaluate feature flags and access their values based on their type. This includes examples for boolean, string, and complex object feature types. ```go // Boolean feature result := client.EvalFeature(ctx, "dark-mode") if result.Value.(bool) { // Enable dark mode } // String feature result := client.EvalFeature(ctx, "button-color") color := result.Value.(string) // "red", "blue", etc. // Complex object result := client.EvalFeature(ctx, "pricing-config") config := result.Value.(map[string]any) ``` -------------------------------- ### Sticky Bucketing Workflow Example Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/sticky-bucketing.md Illustrates the sticky bucketing workflow: initial hash-based bucketing, storing the assignment, subsequent sticky retrieval, and re-bucketing upon experiment version changes. ```go // Initial evaluation (bucket version 0) result1 := client.RunExperiment(ctx, exp) // HashBased: "control" // Assignment saved: "my-exp__0" -> "control" // Later evaluation (same bucket version) result2 := client.RunExperiment(ctx, exp) // Sticky: "control" (same as before) // Experiment updated (bucket version now 1) exp.BucketVersion = 1 result3 := client.RunExperiment(ctx, exp) // Re-bucketed: "treatment" // Assignment saved: "my-exp__1" -> "treatment" ``` -------------------------------- ### Checking Experiment Activity Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Example of how to use the `IsActive` method to determine if an experiment should be run. ```go if exp.IsActive() { // Run the experiment } ``` -------------------------------- ### Example Data Source Close Error Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/errors.md Shows an example error message when the data source is not ready or fails during cleanup. ```text "datasource is not ready" ``` -------------------------------- ### Create GrowthBook Client with Options Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/client.md Use `NewClient` to create a new GrowthBook SDK client with custom options. This function initializes plugins and starts background data sources asynchronously. Ensure to handle potential initialization errors and defer client closing. ```go import ( "context" "log" gb "github.com/growthbook/growthbook-golang" ) client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), gb.WithAttributes(gb.Attributes{"id": "user-123"}), gb.WithSseDataSource(), ) if err != nil { log.Fatal("Client creation failed: ", err) } deffer client.Close() ``` -------------------------------- ### Configure Sticky Bucketing with a Service Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/sticky-bucketing.md Use this option to provide an implementation for storing and retrieving sticky bucketing assignments. An in-memory service is shown as an example. ```go service := gb.NewInMemoryStickyBucketService() client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), gb.WithStickyBucketService(service), ) ``` -------------------------------- ### Run an Experiment Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/SUMMARY.txt Execute an experiment and get the assigned variation. This method handles bucketing, sticky bucketing, and tracking. ```go import ( "fmt" "github.com/growthbook/growthbook-golang/growthbook" ) func main() { // Assume gb is an initialized GrowthBook instance // gb := growthbook.NewGrowthBook(...) experiment := growthbook.Experiment{ Key: "my-experiment", Variations: []interface{}{"control", "treatment"}, } experimentResult := gb.Run(experiment.Key, experiment.Variations, "control") // Provide a default value if experimentResult.InExperiment { fmt.Printf("User is in experiment '%s', assigned variation: %v\n", experiment.Key, experimentResult.Value) } else { fmt.Printf("User is NOT in experiment '%s'. Default value: %v\n", experiment.Key, experimentResult.Value) } } ``` -------------------------------- ### Example Client Close Error Output Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/errors.md Illustrates a typical error message when multiple plugins fail during the client close operation. ```text failed to flush events failed to close database ``` -------------------------------- ### Implement Custom Data Source in Go Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/datasources.md Define a custom data source by implementing the `Start`, `backgroundRefresh`, and `Close` methods. This allows for custom feature loading and background updates. ```go type MyDataSource struct { client *Client cancel context.CancelFunc } func (ds *MyDataSource) Start(ctx context.Context) error { ctx, ds.cancel = context.WithCancel(ctx) // Load initial features resp, err := ds.client.CallFeatureApi(ctx, "") if err != nil { return err } if err := ds.client.UpdateFromApiResponse(resp); err != nil { return err } // Start background refresh loop go ds.backgroundRefresh(ctx) return nil } func (ds *MyDataSource) backgroundRefresh(ctx context.Context) { ticker := time.NewTicker(10 * time.Minute) defer ticker.Stop() for { select { case <-ctx.Done(): return case <-ticker.C: resp, err := ds.client.CallFeatureApi(ctx, "") if err != nil { ds.client.Logger().Error("Refresh failed", "error", err) continue } if err := ds.client.UpdateFromApiResponse(resp); err != nil { ds.client.Logger().Error("Update failed", "error", err) } } } } func (ds *MyDataSource) Close() error { ds.cancel() return nil } // Register with client client, err := gb.NewClient( context.Background(), gb.WithDataSource(&MyDataSource{client: client}), ) ``` -------------------------------- ### Metrics Plugin (Prometheus Example) Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/plugins.md Implement a metrics plugin using Prometheus to count experiment and feature evaluations. This plugin initializes Prometheus counters and increments them on relevant events. ```go import "github.com/prometheus/client_golang/prometheus" type MetricsPlugin struct { experimentCounter prometheus.Counter featureCounter prometheus.Counter } func (p *MetricsPlugin) Init(client *Client) error { p.experimentCounter = prometheus.NewCounter(prometheus.CounterOpts{ Name: "growthbook_experiments_total", Help: "Total experiments evaluated", }) p.featureCounter = prometheus.NewCounter(prometheus.CounterOpts{ Name: "growthbook_features_total", Help: "Total features evaluated", }) return nil } func (p *MetricsPlugin) OnExperimentViewed(ctx context.Context, exp *Experiment, result *ExperimentResult) { if result.InExperiment { p.experimentCounter.Inc() } } func (p *MetricsPlugin) OnFeatureEvaluated(ctx context.Context, key string, result *FeatureResult) { p.featureCounter.Inc() } func (p *MetricsPlugin) Close() error { return nil } ``` -------------------------------- ### Get Client Configuration Details Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/README.md Retrieves the client key, HTTP client, and logger instance associated with the GrowthBook client. Useful for debugging or custom integrations. ```go key := client.ClientKey() httpClient := client.HttpClient() logger := client.Logger() ``` -------------------------------- ### Example VariationMeta Assignment Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Example of assigning VariationMeta to an experiment. This configures the variations available for an experiment, including a holdout group. ```go exp.Meta = []gb.VariationMeta{ {Key: "control", Name: "Control"}, {Key: "treatment", Name: "Treatment A", Passthrough: false}, {Key: "holdout", Name: "Holdout Group", Passthrough: true}, } ``` -------------------------------- ### Set Up GrowthBook Client with SSE Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/INDEX.md Initialize a GrowthBook client with a client key and enable Server-Sent Events (SSE) for real-time data updates. ```go client, _ := gb.NewClient(ctx, gb.WithClientKey("sdk-XXX"), gb.WithSseDataSource()) ``` -------------------------------- ### DataSource Interface Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/types.md Interface for feature data sources. It defines methods for starting and closing the data source. ```APIDOC ## DataSource Interface ### Description Interface for feature data sources. It defines methods for starting and closing the data source. ### Methods - `Start(context.Context) error`: Starts the data source. - `Close() error`: Closes the data source. ``` -------------------------------- ### Configure GrowthBook Client with Environment Variables Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/configuration.md Initialize the GrowthBook client by reading API host and client key from environment variables. Logs a fatal error if the client key is not set. ```go apiHost := os.Getenv("GB_API_HOST") if apiHost == "" { apiHost = "https://cdn.growthbook.io" } clientKey := os.Getenv("GB_CLIENT_KEY") if clientKey == "" { log.Fatal("GB_CLIENT_KEY environment variable not set") } client, err := gb.NewClient( context.Background(), gb.WithApiHost(apiHost), gb.WithClientKey(clientKey), ) ``` -------------------------------- ### Close GrowthBookTrackingPlugin Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/plugins.md Example of using the Close method with defer to ensure pending events are flushed before the client exits. ```go client, _ := gb.NewClient(ctx, gb.WithGrowthBookTracking(config)) deffer client.Close() // Flushes pending events before exit ``` -------------------------------- ### Static Features (No Background Source) Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/README.md Initialize the client with a static set of features using `gb.WithFeatures()`. This approach does not fetch updates from a background source and requires manual refreshing if needed. ```go features := gb.FeatureMap{ "feature-1": &gb.Feature{DefaultValue: false}, } client, _ := gb.NewClient( context.Background(), gb.WithFeatures(features), ) // No automatic updates; refresh manually if needed ``` -------------------------------- ### Run Experiment with Sticky Bucketing Source: https://github.com/growthbook/growthbook-golang/blob/main/README.md Execute an experiment using a GrowthBook client that has sticky bucketing enabled. The `RunExperiment` method will utilize the configured sticky bucket service to ensure consistent bucketing. ```go // Run an experiment with sticky bucketing exp := &gb.Experiment{ Key: "my-experiment", Variations: []gb.FeatureValue{"control", "treatment"}, Meta: []gb.VariationMeta{ {Key: "0"}, // Use numeric keys to match variation IDs {Key: "1"}, }, BucketVersion: 1, MinBucketVersion: 0, } result := client.RunExperiment(context.Background(), exp) ``` -------------------------------- ### Feature Truthiness Check Example Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Shows how to check if a feature is truthy or falsy using the `On` and `Off` properties of the evaluation result. ```go result := client.EvalFeature(ctx, "feature") if result.On { // Feature is truthy } if result.Off { // Feature is falsy } ``` -------------------------------- ### Example of ErrNoDecryptionKey Trigger Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/errors.md Illustrates a scenario where ErrNoDecryptionKey would be returned if a decryption key is not provided during client initialization. ```go client, _ := gb.NewClient(context.Background()) err := client.SetEncryptedJSONFeatures(encryptedPayload) // err: "no decryption key provided" ``` -------------------------------- ### Basic GrowthBook Go SDK Usage Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/README.md Demonstrates basic usage of the GrowthBook Go SDK, including client creation, feature loading, attribute assignment, and feature evaluation. The client should be closed when no longer needed. ```go import gb "github.com/growthbook/growthbook-golang" // Create a client client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), gb.WithSseDataSource(), ) defer client.Close() // Wait for features to load err = client.EnsureLoaded(context.Background()) // Create a child client with user attributes child, _ := client.WithAttributes(gb.Attributes{ "id": "user-123", "email": "user@example.com", }) // Evaluate a feature result := child.EvalFeature(context.Background(), "feature-key") if result.On { // Feature is enabled } ``` -------------------------------- ### Evaluate Feature Value Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/SUMMARY.txt Get the evaluated value of a feature flag. The `FeatureValue` type can represent any JSON-serializable value. ```go import ( "fmt" "github.com/growthbook/growthbook-golang/growthbook" ) func main() { // Assume gb is an initialized GrowthBook instance // gb := growthbook.NewGrowthBook(...) featureResult := gb.EvalFeature("my-feature") if featureResult.On { fmt.Printf("Feature 'my-feature' is ON with value: %v\n", featureResult.Value) } else { fmt.Printf("Feature 'my-feature' is OFF\n") } // You can also check specific types stringValue, ok := featureResult.Value.(string) if ok { fmt.Printf("Feature value as string: %s\n", stringValue) } } ``` -------------------------------- ### Initialize and Check Data Source Status in Golang Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/datasources.md Use this snippet to initialize the GrowthBook client with an SSE data source and verify if it has loaded successfully. This is crucial for ensuring features can be evaluated correctly. Errors during initialization or loading will be logged. ```go client, err := gb.NewClient(ctx, gb.WithSseDataSource()) if err != nil { log.Fatal(err) // Client creation failed } // Check if data source started if err := client.EnsureLoaded(context.Background()); err != nil { log.Fatal("Data source failed: ", err) } // Evaluate features - safe to use even if data source failed result := client.EvalFeature(ctx, "feature") // Returns unknown feature result if no features loaded ``` -------------------------------- ### PollDataSource.Start Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/datasources.md Initializes polling for the PollDataSource. This method loads initial features and starts a background ticker that polls at the configured interval. ```APIDOC ## PollDataSource.Start ### Description Initializes polling for the PollDataSource. This method loads initial features and starts a background ticker that polls at the configured interval. ### Method `func (ds *PollDataSource) Start(ctx context.Context) error` ### Behavior - Loads initial features via HTTP GET - Starts a background ticker that polls at the configured interval - Uses ETags to avoid re-downloading unchanged data ### Returns Error if initial feature load fails. ### Source `datasource_poll.go:37` ``` -------------------------------- ### DataSource Interface Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/datasources.md Interface for custom data source implementations. It defines methods for starting and closing the data fetching process. ```APIDOC ## DataSource Interface ### Description Interface for custom data source implementations. It defines methods for starting and closing the data fetching process. ### Methods - **Start** (`context.Context`) error: Initialize and begin fetching features; called in background goroutine. - **Close** () error: Stop fetching and cleanup resources. ### Implementation Notes - `Start` is called in a background goroutine after the client is created. - `Start` should be non-blocking; use goroutines for ongoing work. - `Close` must be safe to call after `Start` completes. - Errors from `Start` are logged but don't prevent client creation. ``` -------------------------------- ### Sticky Bucketing Service Initialization Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/sticky-bucketing.md Initializes a GrowthBook client with a sticky bucket service. If the service fails to retrieve assignments, the error is logged, and the experiment falls back to hash-based bucketing. ```go client, _ := gb.NewClient( context.Background(), gb.WithStickyBucketService(service), ) // If service.GetAssignments fails: // - Error is logged // - Experiment falls back to hash-based bucketing // - Result is returned (possibly different from previous evaluation) ``` -------------------------------- ### Initialize Client with In-Memory Sticky Bucket Service Source: https://github.com/growthbook/growthbook-golang/blob/main/README.md Create a GrowthBook client configured with an in-memory sticky bucket service for consistent experiment variation assignment across sessions and devices. This service is thread-safe and caches assignments. ```go // Create an in-memory sticky bucket service service := gb.NewInMemoryStickyBucketService() // Create a client with sticky bucketing client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), gb.WithStickyBucketService(service), ) ``` -------------------------------- ### Init Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/plugins.md Initializes the GrowthBookTrackingPlugin with client configuration. It copies essential details like the client key and HTTP client from the main client. If the client key is empty, the plugin becomes a silent no-op. ```APIDOC ## Init Initializes the plugin with client configuration. ### Method ```go func (p *GrowthBookTrackingPlugin) Init(client *Client) error ``` ### Returns - `error` - `fmt.Errorf("growthbook tracking plugin requires a client key")` if client key is missing; nil on success. ### Behavior - Copies client key, HTTP client, and logger from the client - Returns error if client key is empty; plugin becomes a silent no-op - Failed plugin callbacks do nothing ### Side Effects - Sets plugin's `initialized` flag (used by callback methods) - Extracts configuration from client if not provided in config ``` -------------------------------- ### Get Logger Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/client.md Retrieves the configured logger instance used by the client. This logger is set via WithLogger or defaults to a standard logger. ```go logger := client.Logger() logger.Info("Custom log message") ``` -------------------------------- ### Minimal GrowthBook Client Configuration Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/configuration.md Initialize the GrowthBook client with the most basic configuration, relying on default values for all settings except the API host and client key which are implicitly handled. ```go // Minimal configuration (no data source) client, _ := gb.NewClient(context.Background()) ``` -------------------------------- ### Get Client Key Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/client.md Retrieves the SDK client key used for API authentication. Returns an empty string if no key was configured. ```go key := client.ClientKey() ``` -------------------------------- ### Complete GrowthBook Golang Client Configuration Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/configuration.md This snippet shows how to create and configure a GrowthBook client with a full set of options. It includes API host, client key, decryption key, data source configuration, user attributes, sticky bucketing, experiment and feature callbacks, logging, HTTP client, and tracking plugins. Ensure all necessary imports are present. ```go import ( "context" "log/slog" "net/http" "os" "time" gb "github.com/growthbook/growthbook-golang" ) // Create HTTP client with custom settings httpClient := &http.Client{ Timeout: 10 * time.Second, } // Create logger logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) // Create sticky bucketing service stickyService := gb.NewInMemoryStickyBucketService() // Create client with full configuration client, err := gb.NewClient( context.Background(), // API configuration gb.WithApiHost("https://api.growthbook.io"), gb.WithClientKey("sdk-1234567890"), gb.WithDecryptionKey("decryption-key"), // Data source gb.WithSseDataSource(), // Attributes gb.WithAttributes(gb.Attributes{ "id": "user-456", "email": "user@example.com", "org": "acme-corp", "role": "admin", }), // Sticky bucketing gb.WithStickyBucketService(stickyService), gb.WithStickyBucketAttributes(gb.StickyBucketAttributes{ "id": "user-456", }), // Experiment control gb.WithEnabled(true), gb.WithQaMode(false), // Callbacks gb.WithExperimentCallback(func(ctx context.Context, exp *gb.Experiment, result *gb.ExperimentResult, extra any) { logger.Info("Experiment assigned", "experiment", exp.Key, "variation", result.VariationId) }), gb.WithFeatureUsageCallback(func(ctx context.Context, key string, result *gb.FeatureResult, extra any) { logger.Debug("Feature evaluated", "feature", key, "value", result.Value) }), gb.WithExtraData("request-id-123"), // Logging gb.WithLogger(logger), gb.WithHttpClient(httpClient), // Plugins gb.WithGrowthBookTracking(gb.TrackingPluginConfig{ IngestorHost: "https://us1.gb-ingest.com", BatchSize: 100, BatchTimeout: 10 * time.Second, }), ) if err != nil { logger.Error("Failed to create client", "error", err) os.Exit(1) } defer client.Close() // Wait for initial feature load if err := client.EnsureLoaded(context.Background()); err != nil { logger.Error("Failed to load features", "error", err) os.Exit(1) } // Now use the client result := client.EvalFeature(context.Background(), "feature-key") logger.Info("Feature result", "value", result.Value, "source", result.Source) ``` -------------------------------- ### NewExperiment Function Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Creates a new Experiment with default values. Only the key is required; all other fields are zero-initialized. ```go func NewExperiment(key string) *Experiment ``` -------------------------------- ### Example Feature Flag Definition Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Illustrates how to create a Feature struct with a default value and a rule. The rule includes a condition and a force value. ```go feature := &gb.Feature{ DefaultValue: false, Rules: []gb.FeatureRule{ { Condition: gb.Condition{...}, Force: true, }, }, } ``` -------------------------------- ### Initialize Client for Manual Feature Load Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/datasources.md Initializes the GrowthBook client without a data source. Manually fetch and load features after initialization. ```go client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), // No WithSseDataSource or WithPollDataSource ) // Manually fetch and load features err := client.RefreshFeatures(context.Background()) if err != nil { log.Fatal("Failed to load features: ", err) } ``` -------------------------------- ### BucketRange Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/types.md Defines a range within the [0.0, 1.0) namespace for bucketing users. For example, a range of {0.0, 0.5} represents the first 50% of users. ```APIDOC ## BucketRange ### Description A range representing bucket boundaries within the [0.0, 1.0) namespace. ### Go Struct ```go type BucketRange struct { Min float64 Max float64 } ``` ### Example `{0.0, 0.5}` represents the first 50% of users. ``` -------------------------------- ### Initialize Client with Built-in GrowthBook Tracking Source: https://github.com/growthbook/growthbook-golang/blob/main/README.md Initialize the GrowthBook client with the built-in tracking plugin to automatically send experiment and feature evaluation events to the GrowthBook warehouse. Ensure the client key is valid; otherwise, the plugin acts as a no-op. ```go client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), gb.WithSseDataSource(), gb.WithGrowthBookTracking(gb.TrackingPluginConfig{ // Defaults to "https://us1.gb-ingest.com" IngestorHost: "https://us1.gb-ingest.com", }), ) defer client.Close() // flushes remaining events ``` -------------------------------- ### Get Experiment Assignment Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/SUMMARY.txt Retrieve the assigned variation for an experiment without running the full experiment logic. Useful for checking assignments before deciding to run. ```go import ( "fmt" "github.com/growthbook/growthbook-golang/growthbook" ) func main() { // Assume gb is an initialized GrowthBook instance // gb := growthbook.NewGrowthBook(...) experiment := growthbook.Experiment{ Key: "my-experiment", Variations: []interface{}{"control", "treatment"}, } experimentResult := gb.GetAssignment(experiment.Key, experiment.Variations) if experimentResult.InExperiment { fmt.Printf("Assigned variation for '%s': %v\n", experiment.Key, experimentResult.Value) } else { fmt.Printf("Not assigned to experiment '%s'.\n", experiment.Key) } } ``` -------------------------------- ### Client Creation Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/SUMMARY.txt Demonstrates how to create a new GrowthBook client instance with various configuration options. ```APIDOC ## Client Creation ### Description This section covers the creation of GrowthBook client instances, including basic client creation and the use of various configuration options. ### Constructor Functions - `NewGrowthBook(options ...ClientOption)`: Creates a new GrowthBook client. - `NewChildGrowthBook(parent *GrowthBook, options ...ClientOption)`: Creates a child client inheriting from a parent client. ### Client Options - `WithClientOptions(...)` - `WithAttributes(...)` - `WithURL(...)` - `WithLogger(...)` - `WithHTTPClient(...)` ### Usage Example ```go import "github.com/growthbook/growthbook-golang/growthbook" // Basic client creation client, err := growthbook.NewGrowthBook() if err != nil { // Handle error } // Client creation with options clientWithOptions, err := growthbook.NewGrowthBook( growthbook.WithAttributes(map[string]interface{}{"id": "user-123"}), growthbook.WithURL("http://localhost:9000/api/features/my-features"), ) if err != nil { // Handle error } // Child client creation childClient := growthbook.NewChildGrowthBook(client) ``` ``` -------------------------------- ### Register Custom Plugins with ClientOption Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/plugins.md Use WithPlugins to register custom plugins with the GrowthBook client. Plugins are initialized in order and their errors are logged without stopping SDK initialization. They are also shared with child clients. ```go plugin1 := &MyCustomPlugin{} plugin2 := &AnotherPlugin{} client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), gb.WithPlugins(plugin1, plugin2), ) ``` -------------------------------- ### DataSource Interface Definition Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/datasources.md Defines the interface for custom data source implementations in GrowthBook Golang. The Start method initializes fetching, and Close cleans up resources. ```go type DataSource interface { Start(context.Context) error Close() error } ``` -------------------------------- ### NewExperiment Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/feature-evaluation.md Creates a new experiment with default values. The key is the only required parameter, and other fields are initialized to their zero values. ```APIDOC ## NewExperiment ### Description Creates a new experiment with defaults. ### Method ```go func NewExperiment(key string) *Experiment ``` ### Parameters #### Path Parameters - **key** (string) - Required - Unique experiment identifier ### Returns - ** extit{Experiment}** (*Experiment) - An experiment with the key set; all other fields are zero-initialized. ### Example ```go exp := gb.NewExperiment("color-test") exp.Variations = []gb.FeatureValue{"red", "blue"} exp.Weights = []float64{0.5, 0.5} ``` ``` -------------------------------- ### NewApiClient Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/client.md A convenience constructor for creating a client pre-configured with an API host and client key. This simplifies the setup for clients that will fetch features directly from the GrowthBook API. ```APIDOC ## NewApiClient ### Description A convenience constructor for creating a client pre-configured with an API host and client key. This simplifies the setup for clients that will fetch features directly from the GrowthBook API. ### Function Signature ```go func NewApiClient(apiHost string, clientKey string) (*Client, error) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **apiHost** (`string`) - Required - GrowthBook API host (e.g., "https://api.growthbook.io") - **clientKey** (`string`) - Required - SDK client key for API authentication ### Returns - `(*Client, error)` — A Client configured with the provided API host and key. ### Behavior - Creates a client using `NewClient` with `WithApiHost` and `WithClientKey` options - No data source is configured by default ### Example ```go client, err := gb.NewApiClient( "https://api.growthbook.io", "sdk-XXXX", ) if err != nil { log.Fatal(err) } ``` ``` -------------------------------- ### Sticky Bucketing for Consistent Variations Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/README.md Implement sticky bucketing using `gb.NewInMemoryStickyBucketService()` to ensure users consistently see the same experiment variations across sessions. Configure with `gb.WithStickyBucketService()` and `gb.WithStickyBucketAttributes()`. ```go service := gb.NewInMemoryStickyBucketService() client, _ := gb.NewClient( context.Background(), gb.WithStickyBucketService(service), gb.WithStickyBucketAttributes(gb.StickyBucketAttributes{ "id": "user-123", }), ) // Users see consistent variations across sessions result1 := client.RunExperiment(ctx, exp) // Hash-based: "control" result2 := client.RunExperiment(ctx, exp) // Sticky: "control" (same) ``` -------------------------------- ### Get All Sticky Bucket Assignments Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/sticky-bucketing.md Retrieves assignments for multiple attributes in a single call. This method is useful for batch operations and gracefully skips missing entries. ```go attrs := map[string]string{ "id": "user-123", "email": "user@example.com", } assignments, err := service.GetAllAssignments(attrs) // assignments contains docs for both attributes (if they exist) ``` -------------------------------- ### Create GrowthBook Client with API Host and Key Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/client.md Use `NewApiClient` for a simplified client creation process when you have the API host and client key. This is a convenience function that internally uses `NewClient` with appropriate options. ```go client, err := gb.NewApiClient( "https://api.growthbook.io", "sdk-XXXX", ) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Get HTTP Client Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/client.md Retrieves the HTTP client used for API calls. This client is used by data sources and feature API calls and may be inspected or modified. ```go hc := client.HttpClient() ``` -------------------------------- ### Create Client with Experiment Callback Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/client.md Use WithExperimentCallback to create a new client that invokes a custom function when a user is assigned to an experiment. The callback receives context, experiment details, and the result. Exceptions within the callback do not affect SDK operations. ```go callback := func(ctx context.Context, exp *gb.Experiment, result *gb.ExperimentResult, extra any) { // Send to analytics log.Printf("User bucketed into %s variation %d", exp.Key, result.VariationId) } child, _ := client.WithExperimentCallback(callback) ``` -------------------------------- ### Initialize Client with Custom Tracking Callbacks Source: https://github.com/growthbook/growthbook-golang/blob/main/README.md Configure the GrowthBook client with custom experiment and feature usage callbacks for integrating with your own analytics providers. Extra data can be attached using WithExtraData. ```go client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), gb.WithExperimentCallback(func(ctx context.Context, exp *gb.Experiment, result *gb.ExperimentResult, extraData any) { // Send to your analytics provider }), gb.WithFeatureUsageCallback(func(ctx context.Context, key string, result *gb.FeatureResult, extraData any) { // Track feature usage }), gb.WithExtraData(myAnalyticsService), ) ``` -------------------------------- ### Handling ErrNoDecryptionKey Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/errors.md Demonstrates how to set up a client with a decryption key to avoid the ErrNoDecryptionKey error. ```go client, _ := gb.NewClient( context.Background(), gb.WithDecryptionKey("your-decryption-key"), ) ``` -------------------------------- ### Run an Experiment Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/client.md Runs an experiment and returns the assignment result. Assigns a variation based on hashing and bucketing, calls callbacks, and invokes plugin methods. Panics are recovered and logged. ```go exp := &gb.Experiment{ Key: "color-test", Variations: []gb.FeatureValue{"red", "blue"}, } result := client.RunExperiment(context.Background(), exp) fmt.Printf("User assigned to variation: %v\n", result.Value) ``` -------------------------------- ### Feature Evaluation Always Succeeds in Go Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/errors.md Feature evaluation in Growthbook never returns an error. This example shows how to handle cases where a feature doesn't exist or experiments fail assignment. ```go // These always succeed, never return error: result := client.EvalFeature(ctx, "nonexistent-feature") // result.Source == "unknownFeature" // result.Value == nil result := client.RunExperiment(ctx, &gb.Experiment{...}) // result.InExperiment == false if anything failed ``` -------------------------------- ### Baseline Benchmark Results (2026-04-30) Source: https://github.com/growthbook/growthbook-golang/blob/main/docs/benchmarks/baseline.md Initial benchmark results for the GrowthBook Golang SDK, including performance metrics for feature evaluation, experiment runs, and URL targeting. ```text goos: darwin goarch: arm64 pkg: github.com/growthbook/growthbook-golang cpu: Apple M1 Max BenchmarkEvalFeature_Cold-10 17775379 126.1 ns/op 160 B/op 3 allocs/op BenchmarkEvalFeature_Warm-10 17356208 137.1 ns/op 160 B/op 3 allocs/op BenchmarkRunExperiment-10 10057777 237.9 ns/op 280 B/op 4 allocs/op BenchmarkEvalFeature_Parallel-10 8622685 278.6 ns/op 160 B/op 3 allocs/op BenchmarkIsURLTargeted_Simple-10 289328 8050 ns/op 12139 B/op 126 allocs/op BenchmarkIsURLTargeted_Regex-10 486561 4955 ns/op 8211 B/op 94 allocs/op ``` -------------------------------- ### Create QA Client with Forced Variations Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/README.md Creates a client instance configured for QA mode, allowing forced variation assignments for specific experiments. This ensures consistent results during testing. ```go qaClient, _ := client.WithQaMode(true) qaClient, _ = qaClient.WithForcedVariations(gb.ForcedVariationsMap{ "color-test": 0, }) result := qaClient.EvalFeature(ctx, "color-test") // Always control ``` -------------------------------- ### Create Child Client with Attributes Source: https://github.com/growthbook/growthbook-golang/blob/main/README.md Create a child client instance from a main client, providing session- or query-specific attributes. Child clients automatically receive feature updates from the main client. ```go attrs := gb.Attributes{"id": 100, "user": "Bob"} child, err := client.WithAttributes(attrs) ``` -------------------------------- ### Ensure Data Source Loaded with GrowthBook Golang Client Source: https://github.com/growthbook/growthbook-golang/blob/main/_autodocs/api-reference/client.md Waits for the data source to complete its initial load. Returns immediately if no data source is configured. Handles data source startup errors or context cancellation. ```go func (client *Client) EnsureLoaded(ctx context.Context) error ``` ```go client, _ := gb.NewClient(context.Background(), gb.WithSseDataSource()) if err := client.EnsureLoaded(context.Background()); err != nil { log.Fatal("Data source failed to load: ", err) } // Features are now available ``` -------------------------------- ### Register Custom Plugins Source: https://github.com/growthbook/growthbook-golang/blob/main/README.md Register custom plugins with the GrowthBook client using the `WithPlugins` option during client initialization. Plugins are shared with child clients and handle panics gracefully. ```go client, err := gb.NewClient( context.Background(), gb.WithClientKey("sdk-XXXX"), gb.WithPlugins(myCustomPlugin), ) ```