Disclaimer: This website requires Please enable JavaScript in your browser settings for the best experience.

The availability of features may depend on your plan type. Contact your Customer Success Manager if you have any questions.

Dev guideRecipesAPI ReferenceChangelog
Dev guideAPI ReferenceRecipesChangelogUser GuideGitHubDev CommunityOptimizely AcademySubmit a ticketLog In
Dev guide

OptimizelyConfig for the Go SDK

Describes how to get access to project configuration data within the datafile using OptimizelyConfig for the Optimizely Feature Experimentation Go SDK.

Optimizely Feature Experimentation SDKs open a well-defined set of public APIs, hiding implementation details. However, you may need access to project configuration data within the datafile. The following section extends the public APIs to define data models and access methods, which you can use to access project configuration data.

OptimizelyConfig API

A public configuration data model (OptimizelyConfig) is defined as a structured format of static Optimizely Project data.

Get OptimizelyConfig

You can access OptimizelyConfig through the OptimizelyClient (top-level) using this public API call.

client, err := optimizelyFactory.Client()
if err != nil {
	// handler error
}
var config = client.GetOptimizelyConfig()

getOptimizelyConfig returns an OptimizelyConfig instance containing the following:

  • Environment key
  • SDK key
  • Datafile revision number
  • Experiments mapped by key values
  • All attributes
  • All audiences
  • All events
  • Feature flags mapped by key values
  • Function to retrieve the project configuration (the datafile)

📘

Note

When the system updates the SDK datafile, you can add a notification listener for ProjectConfigUpdateNotification to get notified. After receiving the notification, call the method to get the updated OptimizelyConfig data. Refer to the following examples.

Get datafile

To share the same datafile between multiple SDK instances, such as in a client or server scenario, pass a JSON string representation of the config (the datafile) between instances. To get the datafile, use the OptimizelyConfig object's GetDatafile method. For more information, see Sharing the datafile with multiple SDK implementations.

Object model

The following shows the object model for OptimizelyConfig:

type OptimizelyConfig struct {
	EnvironmentKey string
	SdkKey         string
	Revision       string

	// This experimentsMap is for experiments of legacy projects only.
	// For flag projects, experiment keys are not guaranteed to be unique
	// across multiple flags, so this map may not include all experiments
	// when keys conflict.
	ExperimentsMap map[string]OptimizelyExperiment

	FeaturesMap map[string]OptimizelyFeature
	Attributes  []OptimizelyAttribute
	Audiences   []OptimizelyAudience
	Events      []OptimizelyEvent
}

type OptimizelyExperiment struct {
	ID            string
	Key           string
	Audiences     string
	VariationsMap map[string]OptimizelyVariation
}

type OptimizelyFeature struct {
	ID              string
	Key             string
	ExperimentRules []OptimizelyExperiment
	DeliveryRules   []OptimizelyExperiment
	VariablesMap    map[string]OptimizelyVariable

	// Deprecated: Use experimentRules and deliveryRules
	ExperimentsMap map[string]OptimizelyExperiment
}

type OptimizelyVariation struct {
	ID             string
	Key            string
	FeatureEnabled bool
	VariablesMap   map[string]OptimizelyVariable
}

type OptimizelyVariable struct {
	ID    string
	Key   string
	Type  string
	Value string
}

type OptimizelyAttribute struct {
	ID  string
	Key string
}

type OptimizelyAudience struct {
	ID         string
	Name       string
	Conditions string
}

type OptimizelyEvent struct {
	ID            string
	Key           string
	ExperimentIds []string
}

Examples

You can access OptimizelyConfig from the OptimizelyClient (top-level) using the following code example:

optimizelyConfig := optimizelyClient.GetOptimizelyConfig()

	fmt.Println("[OptimizelyConfig] revision = " + optimizelyConfig.Revision)
	fmt.Println("[OptimizelyConfig] sdkKey = " + optimizelyConfig.SdkKey)
	fmt.Println("[OptimizelyConfig] environmentKey = " + optimizelyConfig.EnvironmentKey)

	fmt.Println("[OptimizelyConfig] attributes:")
	for _, attribute := range optimizelyConfig.Attributes {
		fmt.Println("[OptimizelyAttribute]   -- (id, key) = " + attribute.ID + ", " + attribute.Key)
	}
	fmt.Println("[OptimizelyConfig] audiences:")
	for _, audience := range optimizelyConfig.Audiences {
		fmt.Println("[OptimizelyAudience]   -- (id, name, conditions) = " + audience.ID + ", " + audience.Name + ", " + audience.Conditions)
	}
	fmt.Println("[OptimizelyConfig] events:")
	for _, event := range optimizelyConfig.Events {
		fmt.Println(fmt.Sprintf("[OptimizelyEvent]   -- (id, key, experimentIds) = %s, %s, %v", event.ID, event.Key, event.ExperimentIds))
	}

	// all flags
	flagKeys := []string{}
	for flagKey := range optimizelyConfig.FeaturesMap {
		flagKeys = append(flagKeys, flagKey)
	}

	for _, flagKey := range flagKeys {
		flag := optimizelyConfig.FeaturesMap[flagKey]

		experimentRules := flag.ExperimentRules
		deliveryRules := flag.DeliveryRules

		// use experiment rules and delivery rules and other flag data here...

		for _, experiment := range experimentRules {
			fmt.Println("[OptimizelyExperiment]   - experiment rule-key = " + experiment.Key)
			fmt.Println("[OptimizelyExperiment]   - experiment audiences = " + experiment.Audiences)

			variationKeys := []string{}
			variationsMap := experiment.VariationsMap
			for variationKey, _ := range variationsMap {
				variationKeys = append(variationKeys, variationKey)
			}

			for _, varKey := range variationKeys {
				variation := variationsMap[varKey]
				fmt.Println(fmt.Sprintf("OptimizelyVariation]       -- variation = { key: %s, id: %s, featureEnabled: %v }", varKey, variation.ID, variation.FeatureEnabled))

				variablesMap := variationsMap[varKey].VariablesMap
				variableKeys := []string{}

				for variableKey := range variablesMap {
					variableKeys = append(variableKeys, variableKey)
				}

				for _, variableKey := range variableKeys {
					variable := variablesMap[variableKey]

					fmt.Println(fmt.Sprintf("[OptimizelyVariable]           --- variable: %s, %v", variableKey, variable))
				}
			}
		}

		for _, delivery := range deliveryRules {
			fmt.Println("[OptimizelyExperiment]   - delivery rule-key = " + delivery.Key)
			fmt.Println("[OptimizelyExperiment]   - delivery audiences = " + delivery.Audiences)

			// use delivery rule data here...
		}
	}

	// listen to NotificationType.datafileChange to get updated data
	callback := func(notification notification.ProjectConfigUpdateNotification) {
		var newOptConfig = optimizelyClient.GetOptimizelyConfig()
		fmt.Println("[OptimizelyConfig] revision = " + newOptConfig.Revision)
	}
	optimizelyClient.ConfigManager.OnProjectConfigUpdate(callback)