Create flags in code

10 minute read

Feature flags are conditional statements around coded functionality in an application. In the CloudBees platform, flags are created and evaluated in the context of an application, not an organization. Use the static API to define Boolean, number, and string flags in your application source code.

Create a container class and define feature flags

You can define flags statically or use them dynamically.

  • 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.

  • In the dynamic API approach, you can check flag values directly by name—without defining them beforehand. For example: rox.dynamicApi().isEnabled("someFlag").

Since SDK version 5, flag freezing is disabled by default. To retain flag values for a session or until app launch, you must explicitly set the freeze level.

The following code examples show how to define a Boolean flag, a number flag, and a string flag in various languages.

Android
C client-side
C server-side
C++ client-side
C++ server-side
Go
Java
JavaScript
JavaScript SSR
.NET/C#
Node.js
Objective-C
PHP
Python
React Native
Ruby
Swift
import io.rollout.configuration.RoxContainer; import io.rollout.flags.RoxDouble; import io.rollout.flags.RoxInt; import io.rollout.flags.RoxString; import io.rollout.flags.RoxFlag; public class Container implements RoxContainer { public enum Colors { BLUE, GREEN, YELLOW, WHITE, } public final 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 titleColors = new RoxString("White", new String[]{ "White", "Blue", "Green", "Yellow" }); public final RoxEnum<Colors> titleColorsEnum = new RoxEnum<>(Colors.BLUE); }
#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 the container class of feature flags and set up the SDK key

To use the container class, register its instance with the CloudBees 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.

In the following examples, a Rox SDK function is called to register the class instance, and then the environment key is set up.

Android
C client-side
C server-side
C++ client-side
C++ server-side
Go
Java
JavaScript
JavaScript SSR
.NET/C#
Node.js
Objective-C
PHP
Python
React Native
Ruby
Swift
public class App extends Application { @Override public void onCreate() { super.onCreate(); Container flags = new Container(); Rox.register("<namespace>", flags); Rox.setup("YOUR-SDK-KEY"); // This can also be set up in MainActivity if your app doesn't extend the Application class } }
#include <rox/client.h> #define DEFAULT_API_KEY "<YOUR-SDK-KEY>" int main(int argc, char **argv) { 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")); rox_setup(DEFAULT_API_KEY, NULL); rox_shutdown(); }
#include <rox/server.h> #define DEFAULT_API_KEY "<YOUR-SDK-KEY>" int main(int argc, char **argv) { 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" )); rox_setup(DEFAULT_API_KEY, NULL); rox_shutdown(); }
#include <roxx/client.h> #define DEFAULT_API_KEY "<YOUR-SDK-KEY>" using namespace Rox::Client; int main(int argc, char **argv) { 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"}); Rox::Setup(DEFAULT_API_KEY, NULL); Rox::Shutdown(); }
#include <roxx/server.h> #define DEFAULT_API_KEY "<YOUR-SDK-KEY>" using namespace Rox; int main(int argc, char **argv) { 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"}); Rox::Setup(DEFAULT_API_KEY, NULL); Rox::Shutdown(); }
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 the platform 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 the flag values

The following examples check the feature flag values.

Android
C
C++
Go
Java
JavaScript
JavaScript SSR
.NET/C#
Node.js
Objective-C
PHP
Python
React Native
Ruby
Swift
public class App { public static void main(String[] args) { FeatureFlags flags = new FeatureFlags(); if (flags.videoChat.isEnabled()) { System.out.println("VideoChat Feature is Enabled"); } System.out.println("Title size is " + flags.titleSize.getValue()); System.out.println("The special number is " + flags.specialNumber.getValue()); String color = flags.titleColors.getValue(); if ("Blue".equals(color)) { System.out.println("Title color is blue"); } else if ("Green".equals(color)) { System.out.println("Title color is green"); } else if ("Yellow".equals(color)) { System.out.println("Title color is yellow"); } else if ("White".equals(color)) { System.out.println("Title color is white"); } switch (flags.titleColorsEnum.getValue()) { case BLUE: System.out.println("Title color is blue"); break; case GREEN: System.out.println("Title color is green"); break; case YELLOW: System.out.println("Title color is yellow"); break; case WHITE: System.out.println("Title color is white"); break; } } }
// Check the Boolean flag value if (rox_is_enabled(videoChat)) { // ... } // Check the number flag value printf("Title size is %d\n", rox_get_int(titleSize)); printf("The special number is %f\n", rox_get_double(specialNumber)); // Check the string flag value printf("color is: %s", rox_get_string(titleColor));
// Check the Boolean flag value if (videoChat->IsEnabled()) { // ... } // Check the number flag value std::cout << "Title size is " << titleSize.GetValue() << std::endl; std::cout << "The special number is " << specialNumber.GetValue() << std::endl); // Check the string flag value printf("color is: %s", titleColor->GetValue());
// Check the Boolean flag value if (myFlags.videoChat.IsEnabled(nil)) { // ... } // Check the number flag value console.log('Title size is ' + myFlags.titleSize.getValue()); // Check the string flag value switch myFlags.titleColor.GetValue(nil) { case "Green" : fmt.Println("green"); case "White" : fmt.Println("white"); case "Blue" : fmt.Println("blue"); }
// Check the Boolean flag value public class App { public static void main(String[] args) { FeatureFlags myFlags = new FeatureFlags(); String tag = "MyApp"; if (myFlags.videoChat.isEnabled()) { System.out.println("The video chat feature is enabled"); } // Check the number flag value System.out.println("Title size is " + myFlags.titleSize.getValue()); System.out.println("The special number is " + myFlags.specialNumber.getValue()); // Check the string flag value String color = myFlags.titleColor.getValue(); if ("Blue".equals(color)) { System.out.println("Title color is blue"); } else if ("Green".equals(color)) { System.out.println("Title color is green"); } else if ("Yellow".equals(color)) { System.out.println("Title color is yellow"); } else if ("White".equals(color)) { System.out.println("Title color is white"); } switch (myFlags.titleColorsEnum.getValue()) { case BLUE: System.out.println("Title color is blue"); break; case GREEN: System.out.println("Title color is green"); break; case YELLOW: System.out.println("Title color is yellow"); break; case WHITE: System.out.println("Title color is white"); break; } } }
if (flags.videoChat.isEnabled()) { console.log('The video chat feature is enabled'); } console.log('Title size is ' + flags.titleSize.getValue()); if (flags.titleColor.getValue() === 'Blue') { console.log('Title color is blue'); } else if (flags.titleColor.getValue() === 'Green') { console.log('Title color is green'); } else if (flags.titleColor.getValue() === 'Yellow') { console.log('Title color is yellow'); } else if (flags.titleColor.getValue() === 'White') { console.log('Title color is white'); }
if (flags.videoChat.isEnabled()) { console.log('The video chat feature is enabled'); } console.log('Title size is ' + flags.titleSize.getValue()); if (flags.titleColor.getValue() === 'Blue') { console.log('Title color is blue'); } else if (flags.titleColor.getValue() === 'Green') { console.log('Title color is green'); } else if (flags.titleColor.getValue() === 'Yellow') { console.log('Title color is yellow'); } else if (flags.titleColor.getValue() === 'White') { console.log('Title color is white'); }
if (flags.videoChat.isEnabled() == true) { // videoChat is enabled } Console.WriteLine("Title size is {0}", flags.titleSize.GetValue()); Console.WriteLine("The special number is {0}, flags.specialNumber.GetValue()); if (flags.TitleColorsVariant.GetValue().Equals("Black")) { // set title color to black } else if (flags.TitleColorsVariant.GetValue().Equals("Green")) { // set title color to green }
if (flags.videoChat.isEnabled()) { console.log('The video chat feature is enabled'); } console.log('Title size is ' + flags.titleSize.getValue()); if (flags.titleColor.getValue() === 'Blue') { console.log('Title color is blue'); } else if (flags.titleColor.getValue() === 'Green') { console.log('Title color is green'); } else if (flags.titleColor.getValue() === 'Yellow') { console.log('Title color is yellow'); } else if (flags.titleColor.getValue() === 'White') { console.log('Title color is white'); }
[myContainer.videoChat enabled:^{ NSLog(@"VideoChat Feature is Enabled"); } disabled:^{ // ... }]; NSLog(@"Title size is %i", flags.titleSize.value); NSLog(@"The special number is %f", flags.specialNumber.value); if ([roxContainer.titleColors.value isEqualToString:@"Blue"]) { NSLog(@"Title color is Blue"); } else if ([roxContainer.titleColors.value isEqualToString:@"White"]) { NSLog(@"Title color is White"); } else if ([roxContainer.titleColors.value isEqualToString:@"Green"]) { NSLog(@"Title color is Green"); } else if ([roxContainer.titleColors.value isEqualToString:@"Yellow"]) { NSLog(@"Title color is Yellow"); }
// Check the Boolean flag value if ($container->videoChat->isEnabled()) { echo 'video chat is enabled'; } echo "Title size is " . $container->titleSize->getValue(); echo "The special number is " . $container->specialNumber->getValue(); echo "color is " . $container->titleColors->getValue();
# Check the Boolean flag value if my_flags.video_chat.is_enabled(): print('video_chat is enabled') # Check the number flag value print('Title size is {}'.format(my_flags.title_size.get_value())) print('The special number is {}'.format(my_flags.special_number.get_value())) # Check the string flag value print('color is %s' % my_flags.title_color.get_value())
if (flags.videoChat.isEnabled()) { console.log('The video chat feature is enabled'); } console.log('Title size is ' + flags.titleSize.getValue()); if (flags.titleColor.getValue() === 'Blue') { console.log('Title color is blue'); } else if (flags.titleColor.getValue() === 'Green') { console.log('Title color is green'); } else if (flags.titleColor.getValue() === 'Yellow') { console.log('Title color is yellow'); } else if (flags.titleColor.getValue() === 'White') { console.log('Title color is white'); }
# Check the Boolean flag value if container.video_chat.enabled? puts "video_chat is enabled" end # Check the number flag values puts("Title size is #{container.title_size.value}") puts("The special number is #{container.special_number.value}") puts "color is #{container.title_colors.value}"
flags.videoChat.enabled { print("VideoChat Feature is Enabled") } print("Title size is " + flags.titleSize.value) print("The special number is " + flags.specialNumber.value) switch roxContainer.titleColors!.value()! { case "White": print("Title color is White") case "Blue": print("Title color is Blue") case "Green": print("Title color is Green") case "Yellow": print("Title color is Yellow") default: print("Title color is default - White") } switch roxContainerEnum.titleColors.value { case .White: print("Title color is White") case .Blue: print("Title color is Blue") case .Green: print("Title color is Green") case .Yellow: print("Title color is Yellow") }

The default flag value

The default flag value, used when configuration is disabled or offline, is the value specified in your code. Boolean flags default to false if not explicitly set. Number and string flags require a default value.

Flag freezing is available in client-side SDKs, but disabled by default starting in SDK version 5. If you want a flag to retain its value until relaunch, explicitly define the freeze level, for example, Freeze.UntilLaunch.