Ruby SDK Reference

Updated 3 months ago by Archana Singh

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

  1. 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.
  2. Ensure that you have created your SDK Key. See Create an SDK Key.
  3. 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.
    1. On the Ruby SDK GitHub page, click Code and then clone the sample application. For more information, see Cloning a repository.
    2. 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


Please Provide Feedback