The flag implementation reference provides code examples for defining feature flags and registering SDK instances across all supported languages. Use this reference when implementing flags in your application code. For SDK installation instructions, refer to Install client-side SDKs and Install server-side SDKs. For guidance on running multiple SDK instances, refer to Understanding multiple SDK keys.
Flag types
CloudBees Unify supports three flag types, each representing a different kind of controlled value.
- Boolean flag
-
Represents an on/off feature state. Defaults to
falseif no default value is set. - Number flag
-
Represents an integer (
RoxInt) or double (RoxDouble) value. Requires a default value; accepts an optional list of variations. - String flag
-
Represents a string value (
RoxString). Requires a default value; accepts an optional list of variations.
Flags can also be evaluated dynamically by name without prior definition using the dynamic API (for example, rox.dynamicApi().isEnabled("someFlag")).
Define flags by language
In the static SDK approach, all flags must be defined inside a container class. Each flag name is derived from the variable name in that container.
|
Since SDK version 5, flag freezing is disabled by default. To retain flag values for a session or until app launch, explicitly set the freeze level. |
#import <rox/client.h> RoxStringBase *videoChat = rox_add_flag("demo.video_chat", false); RoxStringBase* titleSize = rox_add_int_with_options("titleSize", 12, ROX_INT_LIST(14, 18, 24)); RoxStringBase* specialNumber = rox_add_double_with_options("specialNumber", 3.14, ROX_DBL_LIST(2.71, 0.577)); RoxStringBase* titleColors = rox_add_string_with_options("demo.titleColors", "White", ROX_LIST_COPY_STR("White", "Blue", "Green", "Yellow"));
#import <rox/server.h> RoxStringBase *videoChat = rox_add_flag("demo.video_chat", false); RoxStringBase* titleSize = rox_add_int_with_options("titleSize", 12, ROX_INT_LIST(14, 18, 24)); RoxStringBase* specialNumber = rox_add_double_with_options("specialNumber", 3.14, ROX_DBL_LIST(2.71, 0.577)); RoxStringBase* titleColors = rox_add_string_with_options("demo.titleColors", "White", ROX_LIST_COPY_STR( "White", "Blue", "Green", "Yellow" ));
#import <roxx/client.h> using namespace Rox::Client; auto videoChat = Rox::Client::Flag::Create("demo.video_chat", false); auto titleSize = Int::Create("titleSize", 12, {14, 18, 24}); auto specialNumber = Double::Create("specialNumber", 3.14, {2.71, 0.577}); auto titleColors = String::Create("demo.titleColors", "White", {"White", "Blue", "Green", "Yellow"});
#import <roxx/server.h> // Consider using #include instead of #import unless using Objective-C++ using namespace Rox; auto videoChat = Rox::Flag::Create("demo.video_chat", false); auto titleSize = Int::Create("titleSize", 12, {14, 18, 24}); auto specialNumber = Double::Create("specialNumber", 3.14, {2.71, 0.577}); auto titleColors = String::Create("demo.titleColors", "White", {"White", "Blue", "Green", "Yellow"});
package main import ( "github.com/rollout/rox-go/v5/server" ) type myContainer struct { videoChat server.RoxFlag titleSize server.RoxInt specialNumber server.RoxDouble titleColor server.RoxString } var myFlags = &myContainer{ // Define a Boolean flag inside the container videoChat: server.NewRoxFlag(false), // Define number flags inside the container titleSize: server.NewRoxInt(12, []int{12, 14, 18, 24}), specialNumber: server.NewRoxDouble(99.9, []float64{10.5, 50.0, 99.9}), // Define a string flag inside the container titleColor: server.NewRoxString("White", []string{"White", "Blue", "Green", "Yellow"}), }
import io.rollout.configuration.RoxContainer; import io.rollout.flags.RoxFlag; import io.rollout.flags.RoxDouble; import io.rollout.flags.RoxInt; import io.rollout.flags.RoxString; public class Flags implements RoxContainer { public enum Colors { BLUE, GREEN, YELLOW, WHITE, } public RoxFlag videoChat = new RoxFlag(); public final RoxInt titleSize = new RoxInt(12, new int[]{ 14, 18, 24 }); public final RoxDouble specialNumber = new RoxDouble(3.14, new double[]{ 2.71, 0.577 }); public final RoxString titleColor = new RoxString("White", new String[]{ "White", "Blue", "Green", "Yellow" }); public final RoxEnum<Colors> titleColorsEnum = new RoxEnum<>(Colors.BLUE); }
const flags = { videoChat: new Rox.Flag(), titleSize: new Rox.RoxNumber(12, [12, 14, 18, 24]), titleColor: new Rox.RoxString('White', ['White', 'Blue', 'Green', 'Yellow']) };
import {Flag} from 'rox-ssr'; const flags = { // Define a Boolean flag inside the container videoChat: new Rox.Flag(), // Define a number flag inside the container titleSize: new Rox.RoxNumber(12, [12, 14, 18, 24]), // Define a string flag inside the container titleColor: new Rox.RoxString('White', ['White', 'Blue', 'Green', 'Yellow']) };
using Io.Rollout.Rox.Server.Flags; public class Container : IRoxContainer { // Define a Boolean flag inside the container public RoxFlag videoChat = new RoxFlag(); // Define number flags inside the container public RoxInt titleSize = new RoxInt(12, new List<int>() { 14, 18, 24 }); public RoxDouble specialNumber = new RoxDouble(3.14, new List<int>() { 2.71, 0.577 }); // Define a string flag inside the container public RoxString TitleColorsVariant = new RoxString("White", new String[] {"White", "Blue", "Green", "Yellow"}); }
const flags = { // Define a Boolean flag inside the container videoChat: new Rox.Flag(), // Define a number flag inside the container titleSize: new Rox.RoxNumber(12, [12, 14, 18, 24]), // Define a string flag inside the container titleColor: new Rox.RoxString('White', ['White', 'Blue', 'Green', 'Yellow']) };
#import <ROXCore/ROXCore.h> @interface Flags : ROXBaseContainer @property (nonatomic) ROXFlag* videoChat; @property (nonatomic) ROXInt* titleSize; @property (nonatomic) ROXDouble* specialNumber; @property (nonatomic) ROXString* titleColors; @end #import "Flags.h" @implementation Flags - (instancetype)init { self = [super init]; if (self) { self.videoChat = [[ROXFlag alloc] init]; self.titleColors = [[ROXString alloc] initWithDefault:@"White" variations:@[@"Blue", @"Green", @"Yellow"]]; self.titleSize = [[ROXInt alloc] initWithDefault:12 variations:@[14, 18, 24]]; self.specialNumber = [[ROXDouble alloc] initWithDefault:3.14 variations:@[2.71, 0.577]]; } return self; } @end
use Rox\Server\Rox; use Rox\Server\Flags\RoxFlag; use Rox\Server\Flags\RoxDouble; use Rox\Server\Flags\RoxInt; use Rox\Server\Flags\RoxString; require __DIR__ . '/vendor/autoload.php'; class Container { public $videoChat; public $titleSize; public $specialNumber; public $titleColors; public function __construct() { $this->videoChat = new RoxFlag(false); $this->titleSize = new RoxInt(12, [14, 18, 24]); $this->specialNumber = new RoxDouble(3.14, [2.71, 0.577]); $this->titleColors = new RoxString("White", ["Blue", "Green", "Yellow"]); } }
from rox.server.flags.rox_flag import RoxFlag # Create a container class class MyContainer: def __init__(self): # Define a Boolean flag inside the container self.video_chat = RoxFlag() # Define a number flag inside the container self.title_size = RoxNumber(12, [12, 14, 18, 24]) # Define a string flag inside the container self.title_color = RoxString('White', ['White', 'Blue', 'Green', 'Yellow'])
const flags = { // Define a Boolean flag inside the container videoChat: new Rox.Flag(), // Define a number flag inside the container titleSize: new Rox.RoxNumber(12, [12, 14, 18, 24]), // Define a string flag inside the container titleColor: new Rox.RoxString('White', ['White', 'Blue', 'Green', 'Yellow']) };
require 'rox/server/rox_server' require 'rox/server/flags/rox_int' require 'rox/server/flags/rox_double' require 'rox/server/flags/rox_string' class MyContainer: attr_reader :video_chat, :title_size, :special_number, :title_colors def initialize @video_chat = Rox::Server::RoxFlag.new @title_size = Rox::Server::RoxInt.new(12, [14, 18, 24]) @special_number = Rox::Server::RoxDouble.new(3.14, [2.71, 0.577]) @title_colors = Rox::Server::RoxString.new('White', ['White', 'Blue', 'Green', 'Yellow']) end end
import Foundation import ROX import ROXCore public class Flags: RoxContainer{ // Define a Boolean flag inside the container public let videoChat = RoxFlag(); // Define number flags inside the container public let titleSize = RoxInt(withDefault: 12, variations: [14, 18, 24]) public let specialNumber = RoxDouble(withDefault: 3.14, variations: [2.71, 0.577]) // Define a string flag inside the container public let titleColors = ROXVariant(withDefault: "White", options: ["White", "Blue", "Green", "Yellow"]) // for Enum-based string flag public let titleColorsEnum = RoxEnumVariant(Colors.White) } enum Colors : Int { case White case Blue case Green case Yellow }
Register a container and set up the SDK key
To use the container class, register its instance with the CloudBees Unify SDK.
The namespace parameter provides logical separation between containers.
A namespace can only be registered once.
|
The SDK key value is shown in the UI when you are viewing flags. The SDK key links your application code to the flag settings you define for each environment. |
rox := server.NewRox() rox.Register(myFlags) <-rox.Setup("<YOUR-SDK-KEY>")
public class App { public static void main(String[] args) { FeatureFlags myFlags = new FeatureFlags(); Rox.register("<namespace>", myFlags); Rox.setup("<YOUR-SDK-KEY>"); } }
Rox.register('<namespace>', flags); Rox.setup("<YOUR-SDK-KEY>");
Rox.register('<namespace>', flags); Rox.setup("<YOUR-SDK-KEY>");
Rox.Register("<namespace>", flags); await Rox.Setup("<YOUR-SDK-KEY>");
Rox.register('<namespace>', flags); await Rox.setup("<YOUR-SDK-KEY>");
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [ROX register:[[Flags alloc] init]]; [ROX setupWithKey:@"<YOUR-SDK-KEY>"]; return YES; }
use Rox\Server\Rox; use Rox\Server\Flags\RoxFlag; use Rox\Server\Flags\RoxString; class Container { public $videoChat; public $titleColors; public function __construct() { $this->videoChat = new RoxFlag(); $this->titleColors = new RoxString("White", ["White", "Blue", "Green", "Yellow"]); } } $container = new Container(); Rox::register(<namespace>, $container); Rox::setup("<YOUR-SDK-KEY>");
# Register the container class instance to {PRODUCT} SDK from rox.server.rox_server import Rox my_flags = MyContainer() Rox.register(<namespace>, my_flags) Rox.setup("<YOUR-SDK-KEY>")
Rox.register('<namespace>', flags); await Rox.setup("YOUR-SDK-KEY");
require 'rox/server/rox_server' class Container end flags = Container.new Rox::Server::RoxServer.register(<namespace>, flags) Rox::Server::RoxServer.setup("<YOUR-SDK-KEY>").join
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { ROX.register("<namespace>", container: Flags()) ROX.setup(withKey: "<YOUR-SDK-KEY>") return true }
Check flag values
The following examples show how to evaluate Boolean, number, and string flag values in each supported language.
Default flag values
The default flag value is the value specified in your code, used when configuration is disabled or offline.
Boolean flags default to false if not explicitly set.
Number and string flags require an explicit default value.
|
Flag freezing is available in client-side SDKs but disabled by default starting in SDK version 5.
To retain a flag’s value until relaunch, explicitly define the freeze level, for example, |