A feature flag engine that can be used to enable, change or rollout features of a system dynamically based on system or user attributes
A system can check for enabled features by performing a REST call to (ex.: /menu) having a JSON body with some input attributes (user info, environment info etc). Some conditions will be evaluated and a JSON containing all enabled features will be returned. Then the client system can use this information to decide on what to enable/disable/configure from its internals.
This was crafted to have complexity of O(1) so that it can support large scale deployments with minimum cost.
This DSL tool will get a JSON written with some feature tree rules and generate a Go code that can be run as a REST service. We use Ruller framework on our code generation and it will be responsible for the runtime execution of those rules.
While developing, enter '/sample' dir and perform docker-compose build
so that you can run your code against sample rules json files and check for results.
If you want to create your own feature flag service, fork https://github.com/flaviostutz/ruller-sample-feature-flag and create your own rules.
Create a project structure just like https://github.com/flaviostutz/ruller-sample-feature-flag
Create infra.json
{
"_config": {
"flatten": true,
},
"_items": [{
"provider": "aws",
"_condition": "randomPerc(10, input:customerid)"
},
{
"provider": "azure",
"_condition": "randomPercRange(10, 50, input:customerid)"
},
{
"provider": "vpsdime"
}
]
}
version: '3.5'
services:
sample:
build: .
environment:
- LOG_LEVEL=info
ports:
- 3001:3000
docker-compose up -d --build
curl -X POST \
http://localhost:3000/rules/infra \
-H 'Content-Type: application/json' \
-H 'X-Forwarded-For: 177.79.35.49' \
-H 'cache-control: no-cache' \
-d '{"customerid": "2118"}
{"_condition_debug":"randomPerc(10, input:customerid)","_rule":"2","provider":"aws"}
curl -X POST \
http://localhost:3000/rules/infra \
-H 'Content-Type: application/json' \
-H 'X-Forwarded-For: 177.79.35.49' \
-H 'cache-control: no-cache' \
-d '{"customerid": "6843"}
{"_condition_debug":"randomPercRange(10, 50, input:customerid)","_rule":"3","provider":"azure"}
--templdir
:--source
: a comma-separated list of Glob patterns or .json
files where ruller-dsl-feature-flag
will read the rules from. Attention: Glob patterns must be enclosed by double quotes on the command line;--target
: the path of the file where the Golang ruller engine will be generated;--templdir
: the path where the template files can be found;--log-level
: the level of logging ruller-dsl-feature-flag
will output to STDOUT;--condition-debug
: if present, the resulting Golang ruller engine will output debug info when processing feature flags;The language is a JSON file with some semantics regarding to feature attributes and condition attributes organized in a tree, so that attributes and conditions from a parent are inherited by its children
Features are identified by an id and may have some custom attributes bound to it. All features whose "condition" attribute evaluates to true will be returned as the result of the REST call
All special functions that this DSL supports can be seen on "_condition" fields on the following sample files
You can also control some rule computation behaviors with the help of _config
key on your .json
file. E.g.
{
"_config": {
"seed": 123,
"default_condition": true,
"lazy_evaluation": true,
"flatten": true
},
"_groups": [...],
"_items": [...]
}
seed
: controls the pseudo-random generator seed in use. Everytime you change it, new random numbers will be assigned from you input;default_condition
: tells which value should be returned when a rule have no condition assigned;lazy_evaluation
: if set to true
, for any missing input the resulting ruller return error on runtime and does not evaluate the rules, even those that have nothing to do with the missing input. The default value of this param is false
, meaning the resulting ruller will evaluate all rules even though an input is missing;flatten
: the output map will get flattened.target
and templdir
runtime parameters on development time. E.g.:go build
./ruller-dsl-feature-flag --source "example-rules/*.json" --target ./rules.go --templdir ./templates