Closed janslow closed 7 months ago
What's interesting is proposal 2 is already supported by jsonlogic, and based on my testing also works fine with flagd and in-memory providers. You do get some warnings but it works - should we just update the schema to reflect this or is there some reason this is discouraged?
Additionally I found that cat
from jsonlogic is not allowed inside the first argument of fractional
, but then when I run it anyway it actually works as expected:
Hey @janslow, thanks for bringing this up. I agree that nested logic is difficult to work with. JsonLogic, the rules engine we leverage behind the scenes, supports chained if/then/else/then logic but some of the libraries we're using do not. I've created and linked issues to add support to those libraries. If those changes are accepted, we can update the JSON schema to allow for chained conditions.
We could potentially add a switch statement, but I would prefer to see if we can get chained if
conditions working.
Requirements
Hey, I'm evaluating flagd and I was wondering if you'd consider implementing an operator that looks up a variant based on the value of a variable?
The use case is that we currently have lots of per-customer targeting in our current system. Whilst some of these can hopefully be replaced with more flexible rules (which is why I'm looking at OpenFeature/flagd), many of them will need to stay this way (e.g., we need to communicate with customers individually before changing which variant they use).
For example, based on the value of the
customerId
context variable, I'd want theexample
flag to evaluate as follows:customerId
iscustomer-A
, evaluate tovariantA
with value"A"
customerId
iscustomer-B1
orcustomer-B2
, evaluate tovariantB
with value"B"
variantC
with value"C"
Currently, the only way to do this would be to have lots of nested if statements, which can get very complex very quickly:
Proposal 1
Add a
switch
rule which acts like aswitch
expression in Go/JavaScript/Java, which takes an input expression, searches all provided "cases" for an exact match and returns the corresponding expression, or returns a default expression.For example, the following flagd config would implement the above use case
A slight variation on the design would be for
cases
to be an array of tuples (e.g.,[["customer-A", "variantA"], ...]
) or array of objects (e.g.,[{ "searchValue": "customer-A", "result": "variantA" }, ...]
), to support any primitive as case keys (i.e.,{ 1: "variantA" }
isn't valid JSON).This can be efficiently evaluated (as long as the case keys are required to be primitives), by pre-building a hash map (or similar) for fast lookups
Proposal 2
Alternatively, a more generic option would be to improve support for "else if" style statements, so that the nested ifs in my original example can be flattened.
For example,
This syntax is similar to an
IFS
expression in most spreadsheet software, with the addition of support for defaults (if there's an odd number of entries, there's a default value).The disadvantage of this is that it's much harder to efficiently evaluate this expression when there's a large number of conditions (e.g., you'd need to look at each case statement and realise that they're all matchers for a single common expression, then build a hash map)