Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,8 @@ jobs:
- name: Check syntax
run: bundle exec ruby -c app.rb

- name: Lint
run: bundle exec rubocop --cache false

- name: Run application
run: bundle exec ruby app.rb
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ source 'https://rubygems.org'
ruby '>= 3.0.0'

# Add your gems here
gem 'featurevisor', '~> 3.0'
gem 'rake', '~> 13.0'
gem 'featurevisor', '~> 2.0'

group :development do
gem 'rubocop', '~> 1.50'
Expand Down
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ GEM
specs:
ast (2.4.3)
benchmark (0.5.0)
featurevisor (2.0.0)
featurevisor (3.0.0)
benchmark (>= 0, < 1)
json (2.21.1)
language_server-protocol (3.17.0.6)
Expand Down Expand Up @@ -41,7 +41,7 @@ PLATFORMS
ruby

DEPENDENCIES
featurevisor (~> 2.0)
featurevisor (~> 3.0)
rake (~> 13.0)
rubocop (~> 1.50)

Expand Down
42 changes: 34 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
# featurevisor-example-ruby

Example Ruby application that demonstrates how to use Featurevisor [Ruby SDK](https://github.com/featurevisor/featurevisor-ruby).
A small Ruby application showing how to use the [Featurevisor Ruby SDK](https://github.com/featurevisor/featurevisor-ruby).

Learn more about Featurevisor [here](https://featurevisor.com).

## Installation
It fetches a production datafile, creates a Featurevisor instance with customer context, then evaluates a flag, a variation, feature variables, and global variables.

Clone the repository, and run:
## Installation

```sh
bundle install
```
$ bundle install

## Run the example

```sh
bundle exec ruby app.rb
```

## Usage
The application evaluates `commerce_platform`, `checkout_experience`, `max_items`, `payment_methods`, `serviceEndpoints`, and `supportContact` from this datafile:

```text
https://featurevisor-example-cloudflare.pages.dev/production/featurevisor-sdk-v3.json
```

Run the server locally, running:
Expected output:

```text
Commerce platform enabled: true
Checkout variation: express
Maximum checkout items: 25
Payment methods: ["card", "wallet"]
Service endpoint: https://api.eu.example.com (timeout: 1200 ms, retries: 4)
Support contact: support-nl@example.com
```
$ rake run

Change the context in `app.rb` to see how Featurevisor selects different rules, variations, and global variable overrides.

## Checks

```sh
bundle exec rubocop
bundle exec ruby app.rb
```

## Featurevisor project

Uses this Featurevisor project to fetch the configuration from: https://github.com/featurevisor/featurevisor-example-cloudflare
The datafile is generated by the [Featurevisor Cloudflare example](https://github.com/featurevisor/featurevisor-example-cloudflare).

Learn more in the [Featurevisor Ruby SDK documentation](https://featurevisor.com/docs/sdks/ruby/).
28 changes: 14 additions & 14 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,33 @@ require 'rake'
task default: [:run]

# Run the Hello World program
desc "Run the Hello World program with Featurevisor"
desc 'Run the Hello World program with Featurevisor'
task :run do
puts "Running Ruby Hello World program with Featurevisor..."
puts 'Running Ruby Hello World program with Featurevisor...'
puts
system("ruby app.rb")
system('ruby app.rb')
end

# Clean temporary files
desc "Clean temporary files"
desc 'Clean temporary files'
task :clean do
puts "Cleaning temporary files..."
FileList["*.log", "*.tmp", "*.temp"].each do |file|
File.delete(file) if File.exist?(file)
puts 'Cleaning temporary files...'
FileList['*.log', '*.tmp', '*.temp'].each do |file|
FileUtils.rm_f(file)
end
puts "Cleanup complete!"
puts 'Cleanup complete!'
end

# Install dependencies
desc "Install gem dependencies"
desc 'Install gem dependencies'
task :install do
puts "Installing gem dependencies..."
system("bundle install")
puts 'Installing gem dependencies...'
system('bundle install')
end

# Run RuboCop
desc "Run RuboCop for code style checking"
desc 'Run RuboCop for code style checking'
task :lint do
puts "Running RuboCop..."
system("bundle exec rubocop")
puts 'Running RuboCop...'
system('bundle exec rubocop')
end
53 changes: 40 additions & 13 deletions app.rb
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,23 +1,50 @@
#!/usr/bin/env ruby

require 'featurevisor'
require 'net/http'
require 'json'
require 'net/http'

DATAFILE_URL = 'https://featurevisor-example-cloudflare.pages.dev/production/featurevisor-sdk-v3.json'.freeze

uri = URI(DATAFILE_URL)
response = Net::HTTP.start(
uri.host,
uri.port,
use_ssl: uri.scheme == 'https',
open_timeout: 10,
read_timeout: 10
) { |http| http.get(uri.request_uri, { 'Accept' => 'application/json' }) }

##
# Fetch datafile
#
datafile_url = "https://featurevisor-example-cloudflare.pages.dev/production/featurevisor-tag-all.json"
response = Net::HTTP.get(URI(datafile_url))
datafile_content = JSON.parse(response, symbolize_names: true)
unless response.is_a?(Net::HTTPSuccess)
raise "Datafile request failed with HTTP #{response.code}"
end

# Create Featurevisor instance
f = Featurevisor.create_featurevisor(
datafile: datafile_content,
datafile: JSON.parse(response.body, symbolize_names: true),
log_level: 'error',
context: {
userId: 'customer-123',
country: 'nl',
locale: 'nl-NL',
accountPlan: 'pro'
}
)

# Get the feature flag value
feature_flag_value = f.is_enabled("my_feature")
begin
commerce_enabled = f.is_enabled('commerce_platform')
checkout_variation = f.get_variation('checkout_experience')
max_items = f.get_variable_integer('checkout_experience', 'max_items')
payment_methods = f.get_variable_array('checkout_experience', 'payment_methods')
endpoints = f.get_variable_object('serviceEndpoints')
support_contact = f.get_variable_string('supportContact')

# Print results to terminal
puts "Feature flag 'my_feature' is enabled: #{feature_flag_value}"
puts "Commerce platform enabled: #{commerce_enabled}"
puts "Checkout variation: #{checkout_variation || 'unavailable'}"
puts "Maximum checkout items: #{max_items || 'unavailable'}"
puts "Payment methods: #{payment_methods || []}"
puts "Service endpoint: #{endpoints[:baseUrl]} " \
"(timeout: #{endpoints[:timeoutMs]} ms, retries: #{endpoints[:retries]})"
puts "Support contact: #{support_contact || 'unavailable'}"
ensure
f.close
end