TotalTechGeek / json-logic-engine

Construct complex rules with JSON & process them.
MIT License
46 stars 9 forks source link

Allow for chaining if statements #30

Closed beeme1mr closed 4 months ago

beeme1mr commented 6 months ago

Hey @TotalTechGeek, thanks for the great library. We're using it as part of a feature flag evaluation engine in a tool called flagd which is a reference implementation of OpenFeature, a CNCF project. Sorry about the link overload 😅 , but I thought the context would help.

We recently had a request to reduce the complexity of a flag definition (extended JsonLogic) by removing the necessity of nesting multiple if conditions. The JsonLogic site mentions that the if operator can take more than 3 arguments to create chained if/then elseif/then logic. However, this json-logic-engine explicitly states that this is not supported at the moment. Would it be possible to add support for this? Thanks!

TotalTechGeek commented 6 months ago

Hi, the documentation is actually incorrect at this point in time, this functionality actually is fully supported!

I will leave this issue open to remind myself to get around to publishing corrected docs

TotalTechGeek commented 6 months ago

@beeme1mr Tattling on myself for bad doc maintenance: https://github.com/TotalTechGeek/json-logic-engine/commit/7793a4d20a10521e43ecf6f2aaed24b809648ad4, it's actually been supported for ~3y

TotalTechGeek commented 6 months ago

By the way -- I've implemented a match statement extension for json-logic-engine for some other projects.

I've tried to avoid straying too far from the original json-logic-js project and adding commands, but do you think it'd be helpful if I introduced this method to the mainline library?

Alternatively, for the use-case described by janslow, it is possible to use get paired with preserve, (though if you want to avoid the cruft of using preserve, you can use the mechanism described here: https://github.com/TotalTechGeek/json-logic-engine/issues/28#issuecomment-2007536872)

This turns it into a dictionary lookup, though you'd need to use "or" for the fallback behavior.

{
    "or": [
        {
            "get": [
                {
                    "preserve": {
                        "a-0": "variantA",
                        "b-0": "variantB",
                        "b-1": "variantB"
                    }
                },
                {
                    "var": "customerId"
                }
            ]
        },
        "variantC"
    ]
}

Also possible, if you can pass variants in as a data point, and would prefer to not embed the data in the logic:


{
    "or": [
        {
            "get": [
                { 
                    "var": "variants"
                },
                {
                    "var": "customerId"
                }
            ]
        },
        "variantC"
    ]
}
beeme1mr commented 6 months ago

Hey @TotalTechGeek, great to hear that chained if/else conditions work already.

We have implementations in many different languages, so changes to JsonLogic need to be ported to all of them. Thanks for the offer, but I think keeping as close as possible to the JsonLogic spec is in our best interest.