growthbook

package module
v0.1.12 Latest Latest
Warning

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

Go to latest
Published: Aug 9, 2023 License: MIT Imports: 9 Imported by: 0

README

GrowthBook Go SDK

GrowthBook is a modular Feature Flagging and Experimentation platform.

This is a Go package that lets you evaluate feature flags and run experiments (A/B tests) within a Go application.

  • No external dependencies
  • Lightweight and fast
  • Local targeting and evaluation, no HTTP requests
  • Use your existing event tracking (GA, Segment, Mixpanel, custom)
  • Run mutually exclusive experiments with namespaces

Installation

go get github.com/growthbook/growthbook-golang

Quick Usage

The main public API for the SDK is provided through the Context and GrowthBook types. The Context type provides a means to pass settings to the main GrowthBook type, while the GrowthBook type provides a Feature method for accessing feature values, and a Run method for running inline experiments. (See below for a more complete code example.)

// Parse feature map from JSON data.
features := growthbook.ParseFeatureMap(jsonBody)

// Create context and main GrowthBook object.
context := growthbook.NewContext().WithFeatures(features)
gb := growthbook.New(context)

// Perform feature test.
if gb.Feature("my-feature").On {
  // ...
}

color := gb.Feature("signup-button-color").GetValueWithDefault("blue")
fmt.Println(color)

experiment :=
  growthbook.NewExperiment("my-experiment").
    WithVariations("A", "B")

result := gb.Run(experiment)

fmt.Println(result.Value)

experiment2 :=
  growthbook.NewExperiment("complex-experiment").
    WithVariations(
      map[string]string{"color": "blue", "size": "small"},
      map[string]string{"color": "green", "size": "large"},
    ).
    WithWeights(0.8, 0.2).
    WithCoverage(0.5)

result2 := gb.Run(experiment2)
fmt.Println(result2.Value.(map[string]string)["color"],
  result2.Value.(map[string]string)["size"])

The GrowthBook Context

A new Context is created using the NewContext function and its fields can be set using the WithEnabled, WithAttributes, WithURL, WithFeatures, WithForcedVariations, WithQAMode and WithTrackingCallback methods. These With... methods return a Context pointer to enable call chaining. Context details can alternatively be parsed from JSON data (see JSON data representations). The fields in a Context include information about the user for whom feature results will be evaluated (the Attributes), the features that are defined, plus some additional values to control forcing of feature results under some circumstances.

Given a Context value, a new GrowthBook value can be created using the New function. The GrowthBook type has some getter and setter methods (setters are methods with names of the form With...) for fields of the associated Context. As well as providing access to the underlying Context and exposing the main Feature and Run methods, the GrowthBook type also keeps track of the results of experiments that are performed, in order to implement tracking and experiment subscription callbacks.

For example, assuming that the growthbook package is imported with name "growthbook", the following code will create a Context and GrowthBook value using features parsed from JSON data and some fixed attributes:

// Parse feature map from JSON.
features := growthbook.ParseFeatureMap(featureJSON)

// Create context and main GrowthBook object.
context := growthbook.NewContext().
  WithFeatures(features).
  WithAttributes(growthbook.Attributes{
    "country": "US",
    "browser": "firefox",
  })
gb := growthbook.New(context)
Features

The WithFeatures method of Context takes a FeatureMap value, which is defined as map[string]*Feature, and which can be created from JSON data using the ParseFeatureMap function (see JSON data representations). You can pass a feature map generated this way to the WithFeatures method of Context or GrowthBook:

featureMap := ParseFeatureMap([]byte(
  `{ "feature-1": {...},
     "feature-2": {...},
     "another-feature": {...}
   }`))

gb := NewContext().WithFeatures(featureMap)

If you need to load feature definitions from a remote source like an API or database, you can update the context at any time with WithFeatures.

If you use the GrowthBook App to manage your features, you don't need to build this JSON file yourself -- it will auto-generate one for you and make it available via an API endpoint.

If you prefer to build this file by hand or you want to know how it works under the hood, check out the detailed Feature Definitions section below.

Attributes

You can specify attributes about the current user and request. These are used for two things:

  • Feature targeting (e.g. paid users get one value, free users get another);

  • Assigning persistent variations in A/B tests (e.g. user id "123" always gets variation B).

Attributes can be any JSON data type -- boolean, integer, string, array, or object and are represented by the Attributes type, which is an alias for the generic map[string]interface{} type that Go uses for JSON objects. If you know them up front, you can pass them into Context or GrowthBook using WithAttributes:

gb := growthbook.New(context).
  WithAttributes(Attributes{
    "id":       "123",
    "loggedIn": true,
    "deviceId": "abc123def456",
    "company":  "acme",
    "paid":     false,
    "url":      "/pricing",
    "browser":  "chrome",
    "mobile":   false,
    "country":  "US",
  })

You can also set or update attributes asynchronously at any time with the WithAttributes method. This will completely overwrite the attributes object with whatever you pass in. If you want to merge attributes instead, you can get the existing ones with Attributes:

attrs := gb.Attributes()
attrs["url"] = "/checkout"
gb.WithAttributes(attrs)

Be aware that changing attributes may change the assigned feature values. This can be disorienting to users if not handled carefully. A common approach is to only refresh attributes on navigation, when the window is focused, and/or after a user performs a major action like logging in.

Tracking Callback

Any time an experiment is run to determine the value of a feature, we can run a callback function so you can record the assigned value in your event tracking or analytics system of choice.

context.WithTrackingCallback(func(experiment *growthbook.Experiment,
  result *growthbook.ExperimentResult) {
    // Example using Segment.io
    client.Enqueue(analytics.Track{
      UserId: context.Attributes()["id"],
      Event: "Experiment Viewed",
      Properties: analytics.NewProperties().
        Set("experimentId", experiment.Key).
        Set("variationId", result.VariationID)
    })
  }
)

Error handling

The GrowthBook public API does not return errors under any normal circumstances. The intention is for developers to be able to use the SDK in both development and production smoothly. To this end, error reporting is provided by a configurable logging interface.

For development use, the DevLogger type provides a suitable implementation of the logging interface: it prints all logged messages to standard output, and exits on errors.

For production use, a logger that directs log messages to a suitable centralised logging facility and ignores all errors would be suitable. The logger can of course also signal error and warning conditions to other parts of the program in which it is used.

To be specific about this:

  • None of the functions that create or update Context, GrowthBook or Experiment values return errors.

  • The main GrowthBook.Feature and GrowthBook.Run methods never return errors.

  • None of the functions that create values from JSON data return errors.

For most common use cases, this means that the GrowthBook SDK can be used transparently, without needing to care about error handling. Your server code will never crash because of problems in the GrowthBook SDK. The only effect of error conditions in the inputs to the SDK may be that feature values and results of experiments are not what you expect.

Using Features

The main method, GrowthBook.Feature(key), takes a feature key and uses the stored feature definitions and attributes to evaluate the feature value. It returns a FeatureResult value with the following fields:

  • Value: the JSON value of the feature (or null if not defined), as a FeatureValue value (which is just an alias for interface{}, using Go's default behavior for handling JSON values);
  • On and Off: the JSON value cast to booleans (to make your code easier to read);
  • Source: a value of type FeatureResultSource, telling why the value was assigned to the user. One of UnknownFeatureResultSource, DefaultValueResultSource, ForceResultSource, or ExperimentResultSource.
  • Experiment: information about the experiment (if any) which was used to assign the value to the user.
  • ExperimentResult: the result of the experiment (if any) which was used to assign the value to the user.

Here's an example that uses all of them:

result := gb.Feature("my-feature")

// The JSON value (might be null, string, boolean, number, array, or
// object).
fmt.Println(result.Value)

if result.On {
  // Feature value is truthy (in a Javascript sense)
}
if result.Off {
  // Feature value is falsy
}

// If the feature value was assigned as part of an experiment
if result.Source == growthbook.ExperimentResultSource {
  // Get all the possible variations that could have been assigned
  fmt.Println(result.Experiment.Variations)
}

Defaulting of the values of feature results is assisted by the GetValueWithDefault method on the FeatureResult type. For example, this code evaluates the result of a feature and returns the feature value, defaulting to "blue" if the feature has no value:

color := gb.Feature("signup-button-color").GetValueWithDefault("blue")

Feature Definitions

For details of the JSON format used for feature definitions, consult the documentation for the GrowthBook Javascript SDK. The Go SDK uses exactly the same logic for processing features, and can ingest the same JSON feature definitions as are used by the Javascript SDK (see JSON data representations).

It is possible to create Feature values in the Go SDK by hand, simply by creating Go values of the appropriate types (Feature, FeatureValue, FeatureRule), but the most common use case is likely to be ingesting feature definitions from JSON data using the ParseFeatureMap function.

Inline Experiments

Experiments can be defined and run using the Experiment type and the Run method of the GrowthBook type. Experiment definitions can be created directly as values of the Experiment type, or parsed from JSON definitions using the ParseExperiment function. Passing an Experiment value to the Run method of the GrowthBook type will run the experiment, returing an ExperimentResult value that contains the resulting feature value. This allows users to run arbitrary experiments without providing feature definitions up-front.

experiment :=
  growthbook.NewExperiment("my-experiment").
    WithVariations("red", "blue", "green")

result := gb.Run(experiment)

All other experiment settings (weights, hash attribute, coverage, namespace, condition) are supported when using inline experiments: the Experiment type has With... methods that allow these fields to be set easily (i.e. WithWeights, WithHashAttribute, WithCoverage, WithNamespace, WithCondition).

In addition, there are a few other settings that only really make sense for inline experiments:

  • Force can be set to one of the variation array indexes. Everyone will be immediately assigned the specified value.

  • Active can be set to false to disable the experiment and return the control for everyone.

Inline Experiment Return Value

A call to GrowthBook.Run(experiment) returns a value of type *ExperimentResult:

experiment := growthbook.NewExperiment("my-experiment").
  WithVariations("A", "B")
result := gb.Run(experiment)

// If user is part of the experiment
fmt.Println(result.InExperiment) // true or false

// The index of the assigned variation
fmt.Println(result.VariationID) // 0 or 1

// The value of the assigned variation
fmt.Println(result.Value) // "A" or "B"

// The user attribute used to assign a variation
fmt.Println(result.HashAttribute) // "id"

// The value of that attribute
fmt.Println(result.HashValue) // e.g. "123"

The InExperiment flag is only set to true if the user was randomly assigned a variation. If the user failed any targeting rules or was forced into a specific variation, this flag will be false.

JSON data representations

For interoperability of the GrowthBook Go SDK with versions of the SDK in other languages, the core "input" values of the SDK (in particular, Context and Experiment values and maps of feature definitions) can be created by parsing JSON data. A common use case is to download feature definitions from a central location as JSON, to parse them into a feature map that can be applied to a GrowthBook Context, then using this context to create a GrowthBook value that can be used for feature tests.

A contrived example of how this might work is:

// Download JSON feature file and read file body.
resp, err := http.Get("https://s3.amazonaws.com/myBucket/features.json")
if err != nil {
	log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
	log.Fatal(err)
}

// Parse feature map from JSON.
features, err := ParseFeatureMap(body)
if err != nil {
	log.Fatal(err)
}

// Create context and main GrowthBook object.
context := NewContext().WithFeatures(features)
growthbook := New(context)

// Perform feature test.
if growthbook.Feature("my-feature").On {
	// ...
}

The functions that implement this JSON processing functionality have names like ParseContext, BuildContext, and so on. Each Parse... function process raw JSON data (as a []byte value), while the Build... functions process JSON objects unmarshalled to Go values of type map[string]interface{}. This provides flexibility in ingestion of JSON data.

Tracking and subscriptions

The Context value supports a "tracking callback", which is a function that is called any time an experiment is run to determine the value of a feature, so that users can record the assigned value in an external event tracking or analytics system.

In addition to the tracking callback, the GrowthBook type also supports more general "subscriptions", which are callback functions that are called any time Run is called, irrespective of whether or not a user is included in an experiment. The subscription system ensures that subscription callbacks are only called when the result of an experiment changes, or a new experiment is run.

Complete code example

This shows a complete (although simple) example, demonstrating how to import and use the Go SDK:

package main

import (
	"fmt"
	"log"
	"os"

	growthbook "github.com/growthbook/growthbook-golang"
)

func main() {
	// Set up development logger: logs all messages from GrowthBook SDK
	// and exits on errors.
	growthbook.SetLogger(&growthbook.DevLogger{})

	// Read JSON feature file.
	featureJSON, err := os.ReadFile("features.json")
	if err != nil {
		log.Fatal(err)
	}

	// Parse feature map from JSON.
	features := growthbook.ParseFeatureMap(featureJSON)

	// Create context and main GrowthBook object.
	context := growthbook.NewContext().
		WithFeatures(features).
		WithAttributes(growthbook.Attributes{
			"country": "US",
			"browser": "firefox",
		})
	gb := growthbook.New(context)

	// Perform feature test.
	fmt.Println("test-feature (US, firefox): ", gb.Feature("test-feature").Value)

	// Perform feature test with different user attributes.
	gb.WithAttributes(growthbook.Attributes{
		"country": "AT",
		"browser": "firefox",
	})
	fmt.Println("test-feature (AT, firefox): ", gb.Feature("test-feature").Value)

	// Feature value lookup with default.
	color := gb.Feature("signup-button-color").GetValueWithDefault("blue")
	fmt.Printf("\nsignup-button-color: %s\n", color)

	// Run simple experiment.
	experiment :=
		growthbook.NewExperiment("my-experiment").
			WithVariations("A", "B")

	result := gb.Run(experiment)

	fmt.Printf("\nmy-experiment value: %s\n\n", result.Value)

	// Run more complex experiment.
	experiment2 :=
		growthbook.NewExperiment("complex-experiment").
			WithVariations(
				map[string]string{"color": "blue", "size": "small"},
				map[string]string{"color": "green", "size": "large"},
			).
			WithWeights(0.8, 0.2).
			WithCoverage(0.5)

	result2 := gb.Run(experiment2)
	fmt.Println("complex-experiment values:",
		result2.Value.(map[string]string)["color"],
		result2.Value.(map[string]string)["size"])
}

The features.json file referenced in the above code looks like this:

{
  "test-feature": {
    "defaultValue": 5,
    "rules": [
      {
        "force": 10,
        "condition": {
          "country": { "$in": ["US", "CA"] },
          "browser": "firefox"
        }
      }
    ]
  },
  "signup-button-color": {
    "defaultValue": "green"
  }
}

Documentation

Overview

Package growthbook provides a Go SDK for the GrowthBook A/B testing and feature flagging service.

Index

Constants

View Source
const (
	ErrJSONFailedToParse       = "failed parsing JSON input"
	ErrJSONInvalidType         = "invalid JSON data type"
	ErrCtxJSONInvalidURL       = "invalid URL in JSON context data"
	ErrExpJSONInvalidCondition = "invalid condition in JSON experiment data"
	ErrCondJSONNot             = "invalid $not in JSON condition data"
	ErrCondJSONSequence        = "something wrong in condition sequence"
	ErrCondJSONSequenceElement = "something wrong in condition sequence element"

	WarnJSONUnknownKey            = "unknown key in JSON data"
	WarnCondCompareTypeMismatch   = "types don't match in condition comparison operation"
	WarnExpJSONKeyNotSet          = "key not set in JSON experiment data"
	WarnExpCoverageMustBePositive = "Experiment coverage must be greater than or equal to 0"
	WarnExpCoverageMustBeFraction = "Experiment coverage must be less than or equal to 1"
	WarnExpWeightsWrongLength     = "Experiment weights and variations arrays must be the same length"
	WarnExpWeightsWrongTotal      = "Experiment weights must add up to 1"
	WarnRuleSkipHashAttributeType = "Skip rule because of non-string hash attribute"

	InfoRuleSkipCondition          = "Skip rule because of condition"
	InfoRuleSkipNoHashAttribute    = "Skip rule because of missing hash attribute"
	InfoRuleSkipEmptyHashAttribute = "Skip rule because of empty hash attribute"
	InfoRuleSkipCoverage           = "Skip rule because of coverage"
	InfoRuleSkipUserNotInExp       = "Skip rule because user not in experiment"
)

Message constants used for logging.

Variables

This section is empty.

Functions

func SetLogger

func SetLogger(userLogger Logger)

SetLogger sets up the logging interface used throughout. The idea here is to provide developers with the option of handling errors and warnings in a strict way during development and a lenient way in production. For example, in development, setting a logger that prints a message for all logged output and panics on any logged warning or error might be appropriate, while in production, it would make more sense to log only warnings and errors and to proceed without halting. All GrowthBook SDK functions leave values in a sensible default state after errors, so production systems can essentially ignore any errors.

Types

type Attributes

type Attributes map[string]interface{}

Attributes is an arbitrary JSON object containing user and request attributes.

type Condition

type Condition interface {
	Eval(attrs Attributes) bool
}

Condition represents conditions used to target features/experiments to specific users.

func BuildCondition

func BuildCondition(cond map[string]interface{}) Condition

BuildCondition creates a Condition value from a JSON object represented as a Go map.

func ParseCondition

func ParseCondition(data []byte) Condition

ParseCondition creates a Condition value from raw JSON input.

type Context

type Context struct {
	Enabled          bool
	Attributes       Attributes
	URL              *url.URL
	Features         FeatureMap
	ForcedVariations ForcedVariationsMap
	QAMode           bool
	TrackingCallback ExperimentCallback
}

Context contains the options for creating a new GrowthBook instance.

func BuildContext

func BuildContext(dict map[string]interface{}) *Context

BuildContext creates a Context value from a JSON object represented as a Go map.

func NewContext

func NewContext() *Context

NewContext creates a context with default settings: enabled, but all other fields empty.

func ParseContext

func ParseContext(data []byte) *Context

ParseContext creates a Context value from raw JSON input.

func (*Context) WithAttributes

func (ctx *Context) WithAttributes(attributes Attributes) *Context

WithAttributes sets the attributes for a context.

func (*Context) WithEnabled

func (ctx *Context) WithEnabled(enabled bool) *Context

WithEnabled sets the enabled flag for a context.

func (*Context) WithFeatures

func (ctx *Context) WithFeatures(features FeatureMap) *Context

WithFeatures sets the features for a context (as a value of type FeatureMap, which is a map from feature names to *Feature values).

func (*Context) WithForcedVariations

func (ctx *Context) WithForcedVariations(forcedVariations ForcedVariationsMap) *Context

WithForcedVariations sets the forced variations for a context (as a value of type ForcedVariationsMap, which is a map from experiment keys to variation indexes).

func (*Context) WithQAMode

func (ctx *Context) WithQAMode(qaMode bool) *Context

WithQAMode can be used to enable or disable the QA mode for a context.

func (*Context) WithTrackingCallback

func (ctx *Context) WithTrackingCallback(trackingCallback ExperimentCallback) *Context

WithTrackingCallback is used to set a tracking callback for a context.

func (*Context) WithURL

func (ctx *Context) WithURL(url *url.URL) *Context

WithURL sets the URL for a context.

type DevLogger

type DevLogger struct{}

DevLogger is a logger instance suitable for use in development. It prints all logged messages to standard output, and exits on errors.

func (*DevLogger) Error

func (log *DevLogger) Error(msg string, args ...interface{})

func (*DevLogger) Errorf

func (log *DevLogger) Errorf(format string, args ...interface{})

func (*DevLogger) Info

func (log *DevLogger) Info(msg string, args ...interface{})

func (*DevLogger) Infof

func (log *DevLogger) Infof(format string, args ...interface{})

func (*DevLogger) Warn

func (log *DevLogger) Warn(msg string, args ...interface{})

func (*DevLogger) Warnf

func (log *DevLogger) Warnf(format string, args ...interface{})

type Experiment

type Experiment struct {
	Key           string
	Variations    []FeatureValue
	Weights       []float64
	Active        bool
	Coverage      *float64
	Condition     Condition
	Namespace     *Namespace
	Force         *int
	HashAttribute *string
}

Experiment defines a single experiment.

func BuildExperiment

func BuildExperiment(dict map[string]interface{}) *Experiment

BuildExperiment creates an Experiment value from a JSON object represented as a Go map.

func NewExperiment

func NewExperiment(key string) *Experiment

NewExperiment creates an experiment with default settings: active, but all other fields empty.

func ParseExperiment

func ParseExperiment(data []byte) *Experiment

ParseExperiment creates an Experiment value from raw JSON input.

func (*Experiment) WithActive

func (exp *Experiment) WithActive(active bool) *Experiment

WithActive sets the enabled flag for an experiment.

func (*Experiment) WithCondition

func (exp *Experiment) WithCondition(condition Condition) *Experiment

WithCondition sets the condition for an experiment.

func (*Experiment) WithCoverage

func (exp *Experiment) WithCoverage(coverage float64) *Experiment

WithCoverage sets the coverage for an experiment.

func (*Experiment) WithForce

func (exp *Experiment) WithForce(force int) *Experiment

WithForce sets the forced value index for an experiment.

func (*Experiment) WithHashAttribute

func (exp *Experiment) WithHashAttribute(hashAttribute string) *Experiment

WithHashAttribute sets the hash attribute for an experiment.

func (*Experiment) WithNamespace

func (exp *Experiment) WithNamespace(namespace *Namespace) *Experiment

WithNamespace sets the namespace for an experiment.

func (*Experiment) WithVariations

func (exp *Experiment) WithVariations(variations ...FeatureValue) *Experiment

WithVariations set the feature variations for an experiment.

func (*Experiment) WithWeights

func (exp *Experiment) WithWeights(weights ...float64) *Experiment

WithWeights set the weights for an experiment.

type ExperimentCallback

type ExperimentCallback func(experiment *Experiment, result *ExperimentResult)

ExperimentCallback is a callback function that is executed every time a user is included in an Experiment. It is also the type used for subscription functions, which are called whenever Experiment.Run is called and the experiment result changes, independent of whether a user is inncluded in the experiment or not.

type ExperimentResult

type ExperimentResult struct {
	InExperiment  bool
	VariationID   int
	Value         FeatureValue
	HashAttribute string
	HashValue     string
}

ExperimentResult records the result of running an Experiment given a specific Context.

func BuildExperimentResult

func BuildExperimentResult(dict map[string]interface{}) *ExperimentResult

BuildExperimentResult creates an ExperimentResult value from a JSON object represented as a Go map.

type Feature

type Feature struct {
	DefaultValue FeatureValue
	Rules        []*FeatureRule
}

Feature has a default value plus rules than can override the default.

func BuildFeature

func BuildFeature(val interface{}) *Feature

BuildFeature creates a Feature value from a generic JSON value.

func ParseFeature

func ParseFeature(data []byte) *Feature

ParseFeature creates a single Feature value from raw JSON input.

type FeatureMap

type FeatureMap map[string]*Feature

FeatureMap is a map of feature objects, keyed by string feature IDs.

func BuildFeatureMap

func BuildFeatureMap(dict map[string]interface{}) FeatureMap

BuildFeatureMap creates a FeatureMap value from a JSON object represented as a Go map.

func ParseFeatureMap

func ParseFeatureMap(data []byte) FeatureMap

ParseFeatureMap creates a FeatureMap value from raw JSON input.

type FeatureResult

type FeatureResult struct {
	Value            FeatureValue
	On               bool
	Off              bool
	Source           FeatureResultSource
	Experiment       *Experiment
	ExperimentResult *ExperimentResult
}

FeatureResult is the result of evaluating a feature.

func BuildFeatureResult

func BuildFeatureResult(dict map[string]interface{}) *FeatureResult

BuildFeatureResult creates an FeatureResult value from a JSON object represented as a Go map.

func (*FeatureResult) GetValueWithDefault

func (fr *FeatureResult) GetValueWithDefault(def FeatureValue) FeatureValue

GetValueWithDefault extracts a value from a FeatureResult with a default.

type FeatureResultSource

type FeatureResultSource uint

FeatureResultSource is an enumerated type representing the source of a FeatureResult.

const (
	UnknownFeatureResultSource FeatureResultSource = iota + 1
	DefaultValueResultSource
	ForceResultSource
	ExperimentResultSource
)

FeatureResultSource values.

func ParseFeatureResultSource

func ParseFeatureResultSource(source string) FeatureResultSource

ParseFeatureResultSource creates a FeatureResultSource value from its string representation.

type FeatureRule

type FeatureRule struct {
	Condition     Condition
	Coverage      *float64
	Force         FeatureValue
	Variations    []FeatureValue
	TrackingKey   *string
	Weights       []float64
	Namespace     *Namespace
	HashAttribute *string
}

FeatureRule overrides the default value of a Feature.

func BuildFeatureRule

func BuildFeatureRule(val interface{}) *FeatureRule

BuildFeatureRule creates an FeatureRule value from a generic JSON value.

type FeatureValue

type FeatureValue interface{}

FeatureValue is a wrapper around an arbitrary type representing the value of a feature. Features can return any kinds of values, so this is an alias for interface{}.

func BuildFeatureValues

func BuildFeatureValues(val interface{}) []FeatureValue

BuildFeatureValues creates a FeatureValue array from a generic JSON value.

type ForcedVariationsMap

type ForcedVariationsMap map[string]int

ForcedVariationsMap is a map that forces an Experiment to always assign a specific variation. Useful for QA.

Keys are the experiment key, values are the array index of the variation.

type GrowthBook

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

GrowthBook is the main export of the SDK.

func New

func New(context *Context) *GrowthBook

New created a new GrowthBook instance.

func (*GrowthBook) Attributes

func (gb *GrowthBook) Attributes() Attributes

Attributes returns the attributes from a GrowthBook's context.

func (*GrowthBook) ClearSavedResults

func (gb *GrowthBook) ClearSavedResults()

ClearSavedResults clears out any experiment results saved within a GrowthBook instance (used for deciding whether to send data to subscriptions).

func (*GrowthBook) ClearTrackingData

func (gb *GrowthBook) ClearTrackingData()

ClearTrackingData clears out records of calls to the experiment tracking callback.

func (*GrowthBook) Enabled

func (gb *GrowthBook) Enabled() bool

Enabled returns the enabled flag from a GrowthBook's context.

func (*GrowthBook) Feature

func (gb *GrowthBook) Feature(key string) *FeatureResult

Feature returns the result for a feature identified by a string feature key.

func (*GrowthBook) Features

func (gb *GrowthBook) Features() FeatureMap

Features returns the features from a GrowthBook's context.

func (*GrowthBook) ForcedVariations

func (gb *GrowthBook) ForcedVariations() ForcedVariationsMap

ForcedVariations returns the forced variations from a GrowthBook's context.

func (*GrowthBook) GetAllResults

func (gb *GrowthBook) GetAllResults() map[string]*ExperimentResult

GetAllResults returns a map containing all the latest results from all experiments that have been run, indexed by the experiment key.

func (*GrowthBook) Run

func (gb *GrowthBook) Run(exp *Experiment) *ExperimentResult

Run an experiment. (Uses doRun to make wrapping for subscriptions simple.)

func (*GrowthBook) Subscribe

func (gb *GrowthBook) Subscribe(callback ExperimentCallback) func()

Subscribe adds a callback that is called every time GrowthBook.Run is called. This is different from the tracking callback since it also fires when a user is not included in an experiment.

func (*GrowthBook) URL

func (gb *GrowthBook) URL() *url.URL

URL returns the URL from a GrowthBook's context.

func (*GrowthBook) WithAttributes

func (gb *GrowthBook) WithAttributes(attrs Attributes) *GrowthBook

WithAttributes updates the attributes in a GrowthBook's context.

func (*GrowthBook) WithEnabled

func (gb *GrowthBook) WithEnabled(enabled bool) *GrowthBook

WithEnabled sets the enabled flag in a GrowthBook's context.

func (*GrowthBook) WithFeatures

func (gb *GrowthBook) WithFeatures(features FeatureMap) *GrowthBook

WithFeatures update the features in a GrowthBook's context.

func (*GrowthBook) WithForcedVariations

func (gb *GrowthBook) WithForcedVariations(forcedVariations ForcedVariationsMap) *GrowthBook

WithForcedVariations sets the forced variations in a GrowthBook's context.

func (*GrowthBook) WithURL

func (gb *GrowthBook) WithURL(url *url.URL) *GrowthBook

WithURL sets the URL in a GrowthBook's context.

type Logger

type Logger interface {
	Error(msg string, args ...interface{})
	Errorf(format string, args ...interface{})
	Warn(msg string, args ...interface{})
	Warnf(format string, args ...interface{})
	Info(msg string, args ...interface{})
	Infof(format string, args ...interface{})
}

Logger is a common interface for logging information and warning messages (errors are returned directly by SDK functions, but there is some useful "out of band" data that's provided via this interface).

type Namespace

type Namespace struct {
	ID    string
	Start float64
	End   float64
}

Namespace specifies what part of a namespace an experiment includes. If two experiments are in the same namespace and their ranges don't overlap, they wil be mutually exclusive.

func BuildNamespace

func BuildNamespace(val interface{}) *Namespace

BuildNamespace creates a Namespace value from a generic JSON value.

func ParseNamespace

func ParseNamespace(data []byte) *Namespace

ParseNamespace creates a Namespace value from raw JSON input.

type VariationRange

type VariationRange struct {
	Min float64
	Max float64
}

VariationRange represents a single bucket range.

Jump to

Keyboard shortcuts

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