Ruby SDK Reference
This topic explains how to use the Harness Feature Flags (FF) SDK in your Ruby application. To learn more about using a sample FF SDK code with Ruby application, see the Ruby SDK GitHub repository.
In this topic:
- Before You Begin
- Prerequisites
- Use Harness Feature Flags SDKs with Ruby Applications
- Shut Down the SDK
- Use Feature Flags Metrics
- Use Connectors
- Public API Methods
- Sample FF SDK for Ruby Application
Before You Begin
- Feature Flags Overview
- Getting Started with Feature Flags
- Client-Side and Server-Side SDKs
- Communication Strategy Between SDKs and Harness Feature Flags
Prerequisites
- Create a feature flag in Harness Feature Flags. Feature flags wrap your code and allow you to manage the feature release in a controlled way. See Create a Feature Flag.
- Ensure that you have created your SDK Key. See Create an SDK Key.
- A Ruby application to test your feature flag. If you do not have your Ruby Application, you can download a sample application from the Ruby SDK GitHub repository.
- On the Ruby SDK GitHub page, click Code and then clone the sample application. For more information, see Cloning a repository.
- Import your project in an IDE such as IntelliJ or Eclipse.
Use Harness Feature Flags SDKs with Ruby Applications
Perform the following steps to get started with using the Feature Flags SDK in your Ruby application:
Step 1: Install the FF SDK Dependency
The first step is to install the FF SDK as a dependency in your application using your application's dependency manager. You can use gem for your Ruby applications. Add the following to your project's Gemfile
file:
gem "ff-ruby-server-sdk"
Step 2: Clone the Feature Flag SDK Repository
Run the following command to clone the Feature Flag SDK repository:
git clone --recurse-submodules [email protected]:harness/ff-ruby-server-sdk.git
Step 3: Initialize the SDK
Now that the SDK is cloned, you can configure and initialize it. You should enter your SDK keys when configuring the SDK so that your application is authorized to connect to Harness Feature Flags and retrieve flags for your environment.
CfClient
is a base class that provides all features of the SDK. You can instantiate the SDKs by calling the instance method or by using public constructor (making multiple instances).
require 'ff/ruby/server/sdk/api/config'
require 'ff/ruby/server/sdk/dto/target'
require 'ff/ruby/server/sdk/api/cf_client'
require 'ff/ruby/server/sdk/api/config_builder'
client = CfClient.instance
key = "YOUR_API_KEY_GOES_HERE"
logger = Logger.new(STDOUT)
# Or saving logs into the filesystem with daily rotation:
# logger = Logger.new("example.log", "daily")
config = ConfigBuilder.new
.logger(logger)
.build
client.init(key, config)
config.logger.debug 'We will wait for the initialization'
client.wait_for_initialization
config.logger.debug 'Initialization is complete'
target = Target.new("YOUR_TARGET_NAME")
YOUR_API_KEY
: The SDK keys authorize your application to connect to the CF client. See Step 3: Create an SDK Key.target
: Represents the desired target for which the feature needs to be evaluated.
Step 4: Evaluate Target for Your Feature Flag
Once you have initialized the CF client for a target, evaluate it for your feature flag. A feature flag is evaluated for a particular target.
Evaluation is performed based on the variation types. In case there is no evaluation with the provided ID, the default value is returned. Use the appropriate method to fetch the desired evaluation of a certain type.
Bool Variation
bool_result = client.bool_variation(bool_flag, target, false)
Number Variation
number_result = client.number_variation(number_flag, target, -1)
String Variation
string_result = client.string_variation(string_flag, target, "unavailable !!!")
JSON Variation
json_result = client.json_variation(json_flag, target, JSON.parse("{}"))
Step 5: Verify Flag Configuration Updates
Run the application from your IDE and verify whether the flag variation value displayed on your application page is consistent with the feature flag you created.
Toggle the flag on and off to verify if your application is getting updated.
Shut Down the SDK
When SDK is not needed, for example, when the app is not running, you can shut down the SDK. This can avoid potential memory leaks.
client.close
Use Feature Flags Metrics
You can modify the metrics API endpoint as the following:
config = ConfigBuilder.new
.event_url("SOME_ENDPOINT_URL")
.build
Otherwise, the default metrics endpoint URL is used.
Use Connectors
This feature that allows you to create or use other connectors. Connector is simply a proxy to your data.
connector = YourConnectorImplementation.new
client.init(
key,
config,
connector
)
Public API Methods
The Public API exposes a few methods that you can utilize:
Instantiate, Initialize, and Close
def initialize(api_key = nil, config = nil, connector = nil)
def init(api_key = nil, config = nil, connector = nil)
def wait_for_initialization
def close
Evaluations
def bool_variation(identifier, target, default_value)
def string_variation(identifier, target, default_value)
def number_variation(identifier, target, default_value)
def json_variation(identifier, target, default_value)
Sample FF SDK for Ruby Application
Here is a sample code for using FF SDKs with Ruby applications.
require "logger"
require "securerandom"
require_relative '../lib/ff/ruby/server/sdk/dto/target'
require_relative '../lib/ff/ruby/server/sdk/api/config'
require_relative '../lib/ff/ruby/server/sdk/api/cf_client'
require_relative '../lib/ff/ruby/server/sdk/api/config_builder'
flag_b = "flag1"
flag_n = "flag2"
flag_s = "flag3"
flag_j = "flag4"
clients = {}
targets = {}
logger = Logger.new(STDOUT)
executor = Concurrent::FixedThreadPool.new(100)
keys = {
"Freemium" => "1f3339b4-e004-457a-91f7-9b5ce173eaaf",
"Non-Freemium" => "a30cf6aa-67f2-4545-8ac7-f86709f4f3a0"
}
keys.each do |name, key|
targets[name] = Target.new("ruby_target_" + name)
config = ConfigBuilder.new
.logger(logger)
.build
client = CfClient.new(key, config)
# .config_url("https://config.feature-flags.uat.harness.io/api/1.0")
# .event_url("https://event.feature-flags.uat.harness.io/api/1.0")
client.init
config.logger.debug "We will wait for the initialization"
client.wait_for_initialization
config.logger.debug "Initialization is complete"
clients[name] = client
end
iterations = 10
counted = 0
count_to = keys.size * iterations
logger.debug "To count: " + count_to.to_s
keys.each do |name, key|
client = clients[name]
target = targets[name]
executor.post do
(1..iterations).each do |iteration|
logger.debug name + " :: iteration no: " + iteration.to_s
bool_result = client.bool_variation(flag_b, target, false)
number_result = client.number_variation(flag_n, target, -1)
string_result = client.string_variation(flag_s, target, "unavailable !!!")
json_result = client.json_variation(flag_j, target, JSON.parse("{}"))
logger.debug name + " :: '" + flag_b.to_s + "' has the value of: " + bool_result.to_s
logger.debug name + " :: '" + flag_n.to_s + "' has the value of: " + number_result.to_s
logger.debug name + " :: '" + flag_s.to_s + "' has the value of: " + string_result.to_s
logger.debug name + " :: '" + flag_j.to_s + "' has the value of: " + json_result.to_s
logger.debug "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
counted = counted + 1
logger.debug "Counted: " + counted.to_s
sleep 10
end
end
end
while counted != count_to
sleep(1)
end
clients.each do |name, client|
logger.debug name + " :: closing"
client.close
end