...

Package lduser

import "github.com/launchdarkly/go-sdk-common/v3/lduser"
Overview
Index

Overview ▾

Package lduser defines the older LaunchDarkly SDK model for user properties.

The SDK now uses the type ldcontext.Context to represent an evaluation context that might represent a user, or some other kind of entity, or multiple kinds. But in older SDK versions, this was limited to one kind and was represented by the type lduser.User. This differed from ldcontext.Context in several ways:

  • There was always a single implicit context kind of "user" (ldcontext.DefaultKind).
  • Unlike Context where only a few attributes such as Key and Name have special behavior, the user model defined many other built-in attributes such as Email which, like Name, were constrained to only allow string values. These had specific setter methods in UserBuilder. Non-built-in attributes were considered "custom" attributes, and were enclosed in a "custom" object in JSON representations.

The User type

The SDK now operates only on Contexts, but the former User type is now an alias for ldcontext.Context, so that some code written for the older SDK that referenced the User type can still work-- as long as it is treating the user as an opaque value and not trying to call methods of the old User type on it. For instance, the old User type had attribute accessors like GetEmail() which do not exist in ldcontext.Context.

Updating code while still using UserBuilder

The UserBuilder type has been retained and modified to be a wrapper for ldcontext.Builder, allowing code that used the older model for building users to still work with minor adjustments.

For any code that still uses UserBuilder, the significant differences from older SDK versions are:

  1. The Build method of UserBuilder now returns an ldcontext.Context, so you will need to update any part of your code that referred to the lduser.User type by name.
  2. The SDK no longer supports setting the key to an empty string. If you do this, the returned Context will be invalid (as indicated by its ldcontext.Context.Err method returning an error) and the SDK will refuse to use it for evaluations or events.
  3. The SDK no longer supports setting the Secondary meta-attribute.
  4. Previously, the Anonymous attribute of a user had three states: true, false, or undefined/null. Undefined/null and false were functionally the same in terms of the LaunchDarkly dashboard/indexing behavior, but they were represented differently in JSON and could behave differently if referenced in a flag rule (an undefined/null value would not match "anonymous is false"). Now, the prattributeoperty is a simple boolean defaulting to false, and the undefined state is the same as false.

Migrating from User/UserBuilder to the ldcontext API

It is preferable to update existing code to use the ldcontext package directly, rather than the User type alias and the UserBuilder wrapper. Here are the kinds of changes you may need to make:

- Code that previously created a simple User with only a key should now use ldcontext.New.

// old
user := lduser.NewUser("my-user-key")

// new
user := ldcontext.New("my-user-key")

- Code that previously created a User with an empty string key ("") must be changed to use a non-empty key instead. If you do not care about the value of the key, use an arbitrary value. If you do not want the key to appear on your LaunchDarkly dashboard, set the Anonymous attribute.

- Code that previously used UserBuilder should now use ldcontext.NewBuilder.

- The ldcontext.Builder has fewer attribute-name-specific setter methods: ldcontext.Builder.Name is still a built-in attribute with its own setter, but for all other optional attributes such as Email that you are setting to a string value, you should instead call ldcontext.Builder.SetString and specify the attribute name as the first parameter.

// old
user := lduser.NewUserBuilder("my-user-key").
    Name("my-name").
    Email("my-email").
    Build()

// new
user := ldcontext.NewBuilder("my-user-key").
    Name("my-name").
    SetString("email", "my-email").
    Build()

- The SetCustom method has been replaced by several Set methods for specific value types, and the ldcontext.Builder.SetValue method which takes an ldvalue.Value representing a value of any type (boolean, number, string, array, or object).

// old
user := lduser.NewUserBuilder("my-user-key").
    Custom("my-string-attr", ldvalue.String("value")).
    Custom("my-array-attr", ldvalue.ArrayOf(ldvalue.String("a"), ldvalue.String("b"))).
    Build()

// new
user := ldcontext.NewBuilder("my-user-key").
    SetString("my-string-attr", "value").
    Set("my-array-attr", ldvalue.ArrayOf(ldvalue.String("a"), ldvalue.String("b"))).
    Build()

- Private attributes are now designated by attribute name with ldcontext.Builder.Private, instead of chaining a call to AsPrivateAttribute() after calling the setter.

// old
user := lduser.NewUserBuilder("my-user-key").
    Name("my-name").AsPrivateAttribute().
    Email("my-email").AsPrivateAttribute().
    Build()

// new
user := ldcontext.NewBuilder("my-user-key").
    Name("my-name").
    SetString("email", "my-email").
    Private("name", "email").
    Build()

func NewAnonymousUser

func NewAnonymousUser(key string) ldcontext.Context

NewAnonymousUser creates a new anonymous user context identified by the given key.

This is exactly equivalent to ldcontext.NewBuilder(key).Anonymous(true).Build(). It is provided to ease migration of code that previously used lduser instead of ldcontext.

func NewUser

func NewUser(key string) ldcontext.Context

NewUser creates a new user context identified by the given key.

This is exactly equivalent to ldcontext.New(key). It is provided to ease migration of code that previously used lduser instead of ldcontext.

type User

User is an alias for the type ldcontext.Context, representing an evaluation context.

This is provided as a compatibility helper for application code written for older SDK versions, which used users instead of contexts. See package comments for lduser.

type User = ldcontext.Context

type UserAttribute

UserAttribute is a string type representing the name of a user attribute.

Constants like KeyAttribute describe all of the built-in attributes that existed in the older user model; you may also cast any string to UserAttribute when referencing a custom attribute name. In the newer context model, none of these attribute names except for "key", "name", and "anonymous" have any special significance.

type UserAttribute string
const (
    // KeyAttribute is the standard attribute name corresponding to UserBuilder.Key.
    KeyAttribute UserAttribute = "key"
    // SecondaryKeyAttribute is the standard attribute name corresponding to User.GetSecondaryKey().
    SecondaryKeyAttribute UserAttribute = "secondary"
    // IPAttribute is the standard attribute name corresponding to UserBuilder.IP.
    IPAttribute UserAttribute = "ip"
    // CountryAttribute is the standard attribute name corresponding to UserBuilder.Country.
    CountryAttribute UserAttribute = "country"
    // EmailAttribute is the standard attribute name corresponding to UserBuilder.Email.
    EmailAttribute UserAttribute = "email"
    // FirstNameAttribute is the standard attribute name corresponding to UserBuilder.FirstName.
    FirstNameAttribute UserAttribute = "firstName"
    // LastNameAttribute is the standard attribute name corresponding to UserBuilder.LastName.
    LastNameAttribute UserAttribute = "lastName"
    // AvatarAttribute is the standard attribute name corresponding to UserBuilder.Avatar.
    AvatarAttribute UserAttribute = "avatar"
    // NameAttribute is the standard attribute name corresponding to UserBuilder.Name.
    NameAttribute UserAttribute = "name"
    // AnonymousAttribute is the standard attribute name corresponding to UserBuilder.Anonymous.
    AnonymousAttribute UserAttribute = "anonymous"
)

type UserBuilder

UserBuilder is a mutable object that uses the Builder pattern to specify properties for a user context.

This is a compatibility helper that has been retained to ease migration of code from the older "user" model to the newer "context" model. See the package description of lduser for more about this.

After obtaining an instance of UserBuilder by calling NewUserBuilder, call setter methods such as UserBuilder.Name to specify any additional user properties. Then, call UserBuilder.Build to construct the ldcontext.Context. All of the UserBuilder setters return a reference the same builder, so they can be chained together:

context := NewUserBuilder("user-key").Name("Bob").Email("test@example.com").Build()

Setters for attributes that can be designated private return the type UserBuilderCanMakeAttributePrivate, so you can chain the AsPrivateAttribute method:

context := NewUserBuilder("user-key").Name("Bob").AsPrivateAttribute().Build() // Name is now private

A UserBuilder should not be accessed by multiple goroutines at once.

This is defined as an interface rather than a concrete type only for syntactic convenience (see UserBuilderCanMakeAttributePrivate). Applications should not implement this interface.

type UserBuilder interface {
    // Key changes the unique key for the user being built.
    Key(value string) UserBuilder

    // IP sets the IP address attribute for the user being built.
    IP(value string) UserBuilderCanMakeAttributePrivate

    // Country sets the country attribute for the user being built.
    Country(value string) UserBuilderCanMakeAttributePrivate

    // Email sets the email attribute for the user being built.
    Email(value string) UserBuilderCanMakeAttributePrivate

    // FirstName sets the first name attribute for the user being built.
    FirstName(value string) UserBuilderCanMakeAttributePrivate

    // LastName sets the last name attribute for the user being built.
    LastName(value string) UserBuilderCanMakeAttributePrivate

    // Avatar sets the avatar URL attribute for the user being built.
    Avatar(value string) UserBuilderCanMakeAttributePrivate

    // Name sets the full name attribute for the user being built.
    Name(value string) UserBuilderCanMakeAttributePrivate

    // Anonymous sets the Anonymous attribute for the user context being built.
    //
    // Anonymous means that the context will not be stored in the database that appears on your
    // LaunchDarkly dashboard. It does not imply that the context has no name; you can still set
    // Name or any other properties you want.
    Anonymous(value bool) UserBuilder

    // Custom sets a custom attribute for the user being built.
    //
    //     user := NewUserBuilder("user-key").
    //         Custom("custom-attr-name", ldvalue.String("some-string-value")).AsPrivateAttribute().
    //         Build()
    Custom(attribute string, value ldvalue.Value) UserBuilderCanMakeAttributePrivate

    // CustomAll sets all of the user's custom attributes at once from a ValueMap.
    //
    // UserBuilder has copy-on-write behavior to make this method efficient: if you do not make any
    // changes to custom attributes after this, it reuses the original map rather than allocating a
    // new one.
    CustomAll(ldvalue.ValueMap) UserBuilderCanMakeAttributePrivate

    // SetAttribute sets any attribute of the user being built, specified as a UserAttribute, to a value
    // of type ldvalue.Value.
    //
    // This method corresponds to the GetAttribute method of User. It is intended for cases where user
    // properties are being constructed generically, such as from a list of key-value pairs. Since not
    // all attributes have the same semantics, its behavior is as follows:
    //
    // 1. For built-in attributes, if the value is not of a type that is supported for that attribute,
    // the method has no effect. For Key, the only supported type is string; for Anonymous, the
    // supported types are boolean or null; and for all other built-ins, the supported types are
    // string or null. Custom attributes may be of any type.
    //
    // 2. Setting an attribute to null (ldvalue.Null() or ldvalue.Value{}) is the same as the attribute
    // not being set in the first place.
    //
    // 3. The method always returns the type UserBuilderCanMakeAttributePrivate, so that you can make
    // the attribute private if that is appropriate by calling AsPrivateAttribute(). For attributes
    // that cannot be made private (Key and Anonymous), calling AsPrivateAttribute() on this return
    // value will have no effect.
    SetAttribute(attribute UserAttribute, value ldvalue.Value) UserBuilderCanMakeAttributePrivate

    // Build creates a Context from the current UserBuilder properties.
    //
    // The Context is independent of the UserBuilder once you have called Build(); modifying the UserBuilder
    // will not affect an already-created Context.
    Build() ldcontext.Context
}

func NewUserBuilder

func NewUserBuilder(key string) UserBuilder

NewUserBuilder constructs a new UserBuilder, specifying the user key.

For authenticated users, the key may be a username or e-mail address. For anonymous users, this could be an IP address or session ID.

func NewUserBuilderFromUser

func NewUserBuilderFromUser(fromUser ldcontext.Context) UserBuilder

NewUserBuilderFromUser constructs a new UserBuilder, copying all attributes from an existing user. You may then call setter methods on the new UserBuilder to modify those attributes.

Custom attributes, and the set of attribute names that are private, are implemented internally as maps. Since the User struct does not expose these maps, they are in effect immutable and will be reused from the original User rather than copied whenever possible. The UserBuilder has copy-on-write behavior so that it only makes copies of these data structures if you actually modify them.

type UserBuilderCanMakeAttributePrivate

UserBuilderCanMakeAttributePrivate is an extension of UserBuilder that allows attributes to be made private via UserBuilder.AsPrivateAttribute. All UserBuilderCanMakeAttributePrivate setter methods are the same as UserBuilder, and apply to the original builder.

UserBuilder setter methods for attributes that can be made private always return this interface. See UserBuilder.AsPrivateAttribute for details.

type UserBuilderCanMakeAttributePrivate interface {
    UserBuilder

    // AsPrivateAttribute marks the last attribute that was set on this builder as being a private
    // attribute: that is, its value will not be sent to LaunchDarkly.
    //
    // This action only affects analytics events that are generated by this particular user object. To
    // mark some (or all) user attributes as private for all users, use the Config properties
    // PrivateAttributeName and AllAttributesPrivate.
    //
    // Most attributes can be made private, but Key and Anonymous cannot. This is enforced by the
    // compiler, since the builder methods for attributes that can be made private are the only ones
    // that return UserBuilderCanMakeAttributePrivate; therefore, you cannot write an expression like
    // NewUserBuilder("user-key").AsPrivateAttribute().
    //
    // In this example, FirstName and LastName are marked as private, but Country is not:
    //
    //     user := NewUserBuilder("user-key").
    //         FirstName("Pierre").AsPrivateAttribute().
    //         LastName("Menard").AsPrivateAttribute().
    //         Country("ES").
    //         Build()
    AsPrivateAttribute() UserBuilder

    // AsNonPrivateAttribute marks the last attribute that was set on this builder as not being a
    // private attribute: that is, its value will be sent to LaunchDarkly and can appear on the dashboard.
    //
    // This is the opposite of AsPrivateAttribute(), and has no effect unless you have previously called
    // AsPrivateAttribute() for the same attribute on the same user builder. For more details, see
    // AsPrivateAttribute().
    AsNonPrivateAttribute() UserBuilder
}