Unleash / unleash

Open-source feature management solution built for developers.
https://getunleash.io
Apache License 2.0
11.02k stars 687 forks source link

Feature: Server-side custom activation strategies #303

Closed Willyham closed 5 years ago

Willyham commented 6 years ago

Custom activation strategies are great, but it's not ideal that we have to implement them across multiple different languages. Furthermore, in manyrepo/micro-services world, we're going to have multiple instances of the clients being used. That means that we either have to wrap the client in our own client which can be imported into multiple repos, or duplicate strategy logic between them.

It's not the worst thing in the world, but it would be great if we had the ability to define activation strategies on the server based on a set of primitives. For example:

        {
          "name": "MyCustomStrategy",
          "parameters": {
            "emailList": "['foo@bar.com']"
          },
          "evaluation": {
             "BooleanExpression": {
                "property": "email",
                "operator": "in"
                "parameter": "emailList"
              }
          }
        }

Obviously this becomes quite a complex IDL.

The other option is actually to allow JS expressions which is extremely powerful and would allow arbitrary expressions:

        {
          "name": "MyCustomStrategy",
          "parameters": {
            "emailList": "['foo@bar.com']"
          },
          "evaluation": {
             "expression: "parameters.emailList.includes(properties.email) && someOtherCondition"
          }
        }

I have used the latter to great effect previously which you can read about here: https://eng.uber.com/u4b-ride-policies/

I'd be interested in spending some time working on this if there's consensus about the feature in general.

ivarconr commented 6 years ago

Hi @Willyham,

Thanks for submitting feature suggestions, really appreciated! The title of this Issue is a bit misleading; the whole point of the unleash architecture is to evaluate strategies on the client side, the isEnabled evaluations needs to be fast!

It's not the worst thing in the world, but it would be great if we had the ability to define activation strategies on the server based on a set of primitives

This is actually something I talked with @sveisvei about just the other day. I agree that for most simple strategies just checking some values we should find a more generic way to avoid re-implementing the same logic. For some more complex strategy implementations (e.g. RemoteAdressStrategy supporting IP-ranges it might not be worth the effort.

The only thing that worries me a bit with this approach is that it might be a bit unclear which strategies a client actually supports. It would require that the application actually provides the context fields that the strategy requires. With explicit strategies we can provide a list of supported strategies for a specific app.

That means that we either have to wrap the client in our own client which can be imported into multiple repos, or duplicate strategy logic between them.

Not quite, you only have to put all custom strategies in a shared library that you use in all your projects. That said, we ended up wrapping the client anyway to support internal complexities such as service discovery and reuse of our company specific context-provider.

The other option is actually to allow JS expressions which is extremely powerful and would allow arbitrary expressions

Yes, and this would work great in both Node.js and Java via Nashorn. How easy would it be to evaluate javascript expressions on other platforms, such as Go, .Net and Python?

I'd be interested in spending some time working on this if there's consensus about the feature in general.

I'm positive to the suggestion :+1: Done right this has the potential of making it easier to use Unleash! We just have to find a solution without unnecessary complexity!

It would be nice if we could start with a few use-cases that needs to be supported, before we decide on an internal IDL or javascript expressions.

It would be awesome if you have the capacity to look in to this, and suggest a doable way!

Willyham commented 6 years ago

I understand the need for client-side evaluations for speed - I didn't really think through what I was saying. I suppose the argument for the server implementing a known IDL and having each client be able to evaluate those rules automatically is really what I was asking for. You're right that using JS expressions for something like that clearly doesn't make sense.

xamino commented 4 years ago

So we've hit this snag to. In our case however we'd like a strategy that for example checks the apps URL against a list of known URLs on the server.

So we implemented a custom strategy, on the client, but this means that the list of all allowed URLs is sent to all the clients – which is a security issue because we're leaking client URLs to other clients.

Does this warrant a separate issue, is there a known answer to this, or is this a new aspect for server side strategies to consider?

ivarconr commented 4 years ago

The Unleash Proxy would solve this. Currently it's part of the SaaS offering: https://www.unleash-hosted.com/articles/the-unleash-proxy