mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
Merge pull request #1205 from Unleash/docs/proxy-and-custom-strategies
docs: Add more docs on custom strategies and the proxy
This commit is contained in:
commit
903917c06a
@ -1,79 +1,71 @@
|
||||
---
|
||||
id: custom_activation_strategy
|
||||
title: Custom Activation Strategy
|
||||
title: Custom Activation Strategies
|
||||
---
|
||||
|
||||
Even though Unleash comes with a few powerful [activation strategies](../user_guide/activation-strategies.md) there might be scenarios where you would like to extend Unleash with your own custom strategies.
|
||||
:::tip
|
||||
This document is a reference for custom activation strategies. If you're looking for a guide on how to use them, see the [_how to use custom strategies_ guide](../how-to/how-to-use-custom-strategies.md).
|
||||
:::
|
||||
|
||||
### Example: TimeStamp Strategy {#example-timestamp-strategy}
|
||||
**Custom activation strategies** let you define your own activation strategies to use with Unleash. When the [built-in activation strategies](../user_guide/activation-strategies.md) aren't enough, custom activation strategies are there to provide you with the flexibility you need.
|
||||
|
||||
In this example we want to define an activation strategy offers a scheduled release of a feature toggle. This means that we want the feature toggle to be activated after a given date and time.
|
||||
Custom activation strategies work exactly like the built-in activation strategies when working in the admin UI.
|
||||
|
||||
#### Define custom strategy {#define-custom-strategy}
|
||||
## Definition
|
||||
|
||||
First we need to "define" our new strategy. To add a new "Strategy", open the Strategies tab from the sidebar.
|
||||
![A strategy creation form. It has fields labeled "strategy name" — "TimeStamp" — and "description" — "activate toggle after a given timestamp". It also has fields for a parameter named "enableAfter". The parameter is of type "string" and the parameter description is "Expected format: YYYY-MM-DD HH:MM". The parameter is required.](/img/timestamp_create_strategy.png)
|
||||
|
||||
![A strategy creation form. It has fields labeled \"strategy name\" and \"description\". It also has fields for a parameter named \"enableAfter\". The parameter is of type \"string\" and the description is \"Expected format: YYYY-MM-DD HH:MM\". The parameter is required.](/img/timestamp_create_strategy.png)
|
||||
You define custom activation strategies on your Unleash instance, either via the admin UI or via the API. A strategy contains:
|
||||
|
||||
We name our strategy `TimeStamp` and add one required parameter of type string, which we call `enableAfter`.
|
||||
- A strategy **name**: You'll use this to refer to the strategy in the UI and in code.
|
||||
- An optional **description**: Use this to describe what the strategy should do.
|
||||
- An optional list of **parameters**: Use this to provide the strategy with arguments it should use in its evaluation.
|
||||
|
||||
#### Use custom strategy {#use-custom-strategy}
|
||||
The strategy **name** is the only required parameter, but adding a good **description** will make it easier to remember what a strategy should do. The list of **parameters** lets you pass data from the Unleash instance to the strategy implementation.
|
||||
|
||||
After we have created the strategy definition, we can now decide to use that activation strategy for our feature toggle.
|
||||
### Parameters
|
||||
|
||||
![The strategy configuration screen for the TimeStamp strategy. It shows the strategy from above with a date entered into the \"enableAfter\" field.](/img/timestamp_use_strategy.png)
|
||||
![The strategy configuration screen for the custom "TimeStamp" strategy. The "enableAfter" field says "2021-12-25 00:00".](/img/timestamp_use_strategy.png)
|
||||
|
||||
In the example we want to use our custom strategy for the feature toggle named `demo.TimeStampRollout`.
|
||||
Parameters let you provide arguments to your strategy that it can access for evaluation. When creating a strategy, each parameter can be either required or optional. This marking is to help the user understand what they need to fill out; they can still save the strategy without filling out a required field.
|
||||
|
||||
#### Client implementation {#client-implementation}
|
||||
Each parameter consists of three parts:
|
||||
|
||||
All official client SDK's for Unleash provides abstractions for you to implement support for custom strategies.
|
||||
- a **name**: must be unique among the strategy's parameters.
|
||||
- an optional **description**: describe the purpose or format of the parameter.
|
||||
- a parameter **type**: dictates the kind of input field the user will see in the admin UI and the type of the value in the implementation code.
|
||||
|
||||
> Before you have provided support for the custom strategy; the client will return false, because it does not understand the activation strategy.
|
||||
|
||||
In Node.js the implementation for the `TimeStampStrategy` would be:
|
||||
#### Parameter types
|
||||
|
||||
```javascript
|
||||
class TimeStampStrategy extends Strategy {
|
||||
constructor() {
|
||||
super('TimeStamp');
|
||||
}
|
||||
Each parameter has one of five different parameter types. A parameter's type impacts the kind of controls shown in the admin UI and how it's represented in code.
|
||||
|
||||
isEnabled(parameters, context) {
|
||||
return Date.parse(parameters.enableAfter) < Date.now();
|
||||
}
|
||||
}
|
||||
```
|
||||
Here's an overview over how the types are represented in the JSON payload returned from the Unleash server. The exact types will vary based on your programming language's type system.
|
||||
|
||||
In the example implementation we make use of the library called moment to parse the timestamp and verify that current time is after the specified `enabledAfter` parameter.
|
||||
:::note Unset values
|
||||
Values of *all types* have an empty string (`""`) as the default value. As such, if you don't interact with a control or otherwise set a value, the value will be an empty string, regardless of the value's type.
|
||||
:::
|
||||
|
||||
All parameter injected to the strategy are handled as `string` objects. This means that the strategies needs to parse it to a more suitable format. In this example we just parse it directly to a `Date` type and do the comparison directly. You might want to also consider timezone in a real implementation.
|
||||
| type name | code representation | example value | UI control |
|
||||
|------------|----------------------------------------|---------------|--------------------------|
|
||||
| string | `string` | `"a string"` | A standard input field |
|
||||
| percentage | an `int` between 0 and 100 (inclusive) | `99` | A value slider |
|
||||
| list | `string` (values are comma-separated) | `"one,two"` | A multi-input text field |
|
||||
| number | `string` | `"123"` | A numeric text field |
|
||||
| boolean | `"true"` or `"false"` | `"true"` | An on/off toggle |
|
||||
|
||||
We also have to remember to register the custom strategy when initializing the Unleash client. Full working code example:
|
||||
|
||||
```javascript
|
||||
const { Strategy, initialize, isEnabled } = require('unleash-client');
|
||||
![A strategy with five parameters, one of each type.](/img/strategy-parameters-ui-controls.png)
|
||||
|
||||
class TimeStampStrategy extends Strategy {
|
||||
constructor() {
|
||||
super('TimeStamp');
|
||||
}
|
||||
## Implementation
|
||||
|
||||
isEnabled(parameters, context) {
|
||||
return Date.parse(parameters.enableAfter) < Date.now();
|
||||
}
|
||||
}
|
||||
:::note
|
||||
If you have not implemented the strategy in your client SDK, the check will always return `false` because the client doesn't recognize the strategy.
|
||||
:::
|
||||
|
||||
const instance = initialize({
|
||||
url: 'http://unleash.herokuapp.com/api/',
|
||||
appName: 'unleash-demo',
|
||||
instanceId: '1',
|
||||
strategies: [new TimeStampStrategy()],
|
||||
});
|
||||
While custom strategies are _defined_ on the Unleash server, they must be _implemented_ on the client. All official Unleash client SDKs provide a way for you to implement custom strategies. You should refer to the individual SDK's documentation for specifics, but for an example, you can have a look at the [_Node.js client implementation_ section in the _how to use custom strategies_ guide](../how-to/how-to-use-custom-strategies.md#step-3-a).
|
||||
|
||||
instance.on('ready', () => {
|
||||
setInterval(() => {
|
||||
console.log(isEnabled('demo.TimeStampRollout'));
|
||||
}, 1000);
|
||||
});
|
||||
```
|
||||
The exact method for implementing custom strategies will vary between SDKs, but the server SDKs follow the same patterns. For front-end client SDKs ([Android](../sdks/android-proxy.md), [JavaScript](../sdks/proxy-javascript.md), [React](../sdks/proxy-react.md), [iOS](../sdks/proxy-ios.md)), the custom activation strategy must be implemented in the [Unleash Proxy](../sdks/unleash-proxy.md).
|
||||
|
||||
|
||||
When implementing a strategy in your client, you will get access to the strategy's parameters and the Unleash Context. Again, refer to your specific SDK's documentation for more details.
|
||||
|
128
website/docs/how-to/how-to-use-custom-strategies.md
Normal file
128
website/docs/how-to/how-to-use-custom-strategies.md
Normal file
@ -0,0 +1,128 @@
|
||||
---
|
||||
title: How to use custom activation strategies
|
||||
---
|
||||
|
||||
This guide takes you through how to use [custom activation strategies](../advanced/custom-activation-strategy.md) with Unleash. We'll go through how you define a custom strategy in the admin UI, how you add it to a toggle, and how you'd implement it in a [client SDK](../sdks/index.md).
|
||||
|
||||
In this example we want to define an activation strategy offers a scheduled release of a feature toggle. This means that we want the feature toggle to be activated after a given date and time.
|
||||
|
||||
## Step 1: Define your custom strategy {#step-1}
|
||||
|
||||
1. **Navigate to the strategies view**. Interact with the "Configure" button in the page header and then go to the "Strategies" link in the dropdown menu that appears.
|
||||
|
||||
![A visual guide for how to navigate to the strategies page in the Unleash admin UI. It shows the steps described in the preceding paragraph.](/img/custom-strategy-navigation.png)
|
||||
|
||||
2. **Define your strategy**. Use the "Add new strategy" button to open the strategy creation form. Fill in the form to define your strategy. Refer to [the custom strategy reference documentation](../advanced/custom-activation-strategy.md#definition) for a full list of options.
|
||||
|
||||
![A strategy creation form. It has fields labeled "strategy name" — "TimeStamp" — and "description" — "activate toggle after a given timestamp". It also has fields for a parameter named "enableAfter". The parameter is of type "string" and the parameter description is "Expected format: YYYY-MM-DD HH:MM". The parameter is required.](/img/timestamp_create_strategy.png)
|
||||
|
||||
|
||||
## Step 2: Apply your custom strategy to a feature toggle {#step-2}
|
||||
|
||||
**Navigate to your feature toggle** and **apply the strategy** you just created.
|
||||
|
||||
![The strategy configuration screen for the custom "TimeStamp" strategy from the previous step. The "enableAfter" field says "2021-12-25 00:00".](/img/timestamp_use_strategy.png)
|
||||
|
||||
## Step 3: Implement the strategy in your client SDK {#step-3}
|
||||
|
||||
The steps to implement a custom strategy for your client depend on the kind of client SDK you're using:
|
||||
|
||||
- if you're using a server-side client SDK, follow the steps in [option A](#step-3-a "Step 3 option A: implement the strategy for a server-side client SDK").
|
||||
- if you're using a front-end client SDK ([Android](../sdks/android-proxy.md), [JavaScript](../sdks/proxy-javascript.md), [React](../sdks/proxy-react.md), [iOS](../sdks/proxy-ios.md)), follow the steps in [option B](#step-3-b "Step 3 option B: implementing the strategy for a front-end client SDK")
|
||||
|
||||
### Option A: Implement the strategy for a server-side client SDK {#step-3-a}
|
||||
|
||||
1. **Implement the custom strategy** in your [client SDK](../sdks/index.md). The exact way to do this will vary depending on the specific SDK you're using, so refer to the SDK's documentation. The example below shows an example of how you'd implement a custom strategy called "TimeStamp" for the [Node.js client SDK](../sdks/node.md).
|
||||
|
||||
```js
|
||||
const { Strategy } = require('unleash-client');
|
||||
|
||||
class TimeStampStrategy extends Strategy {
|
||||
constructor() {
|
||||
super('TimeStamp');
|
||||
}
|
||||
|
||||
isEnabled(parameters, context) {
|
||||
return Date.parse(parameters.enableAfter) > Date.now();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. **Register the custom strategy with the Unleash Client**. When instantiating the Unleash Client, provide it with a list of the custom strategies you'd like to use — again: refer to _your_ client SDK's docs for the specifics.
|
||||
|
||||
Here's a full, working example for Node.js. Notice the `strategies` property being passed to the `initialize` function.
|
||||
|
||||
```js
|
||||
const { Strategy, initialize, isEnabled } = require('unleash-client');
|
||||
|
||||
class TimeStampStrategy extends Strategy {
|
||||
constructor() {
|
||||
super('TimeStamp');
|
||||
}
|
||||
|
||||
isEnabled(parameters, context) {
|
||||
return Date.parse(parameters.enableAfter) > Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
const instance = initialize({
|
||||
url: 'http://unleash.herokuapp.com/api/',
|
||||
appName: 'unleash-demo',
|
||||
instanceId: '1',
|
||||
// highlight-next-line
|
||||
strategies: [new TimeStampStrategy()],
|
||||
});
|
||||
|
||||
instance.on('ready', () => {
|
||||
setInterval(() => {
|
||||
console.log(isEnabled('demo.TimeStampRollout'));
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
### Option B: Implement the strategy for a front-end client SDK {#step-3-b}
|
||||
|
||||
Front-end client SDK don't evaluate strategies directly, so you need to implement the **custom strategy in the [Unleash Proxy](../sdks/unleash-proxy.md)**. The below steps assume you're running the Unleash Proxy as a Docker container. If you're running the Unleash Proxy via Node directly, follow the steps for [server-side SDKs](#step-3-a "Step 3 option A: implement the strategy for a server-side client SDK") instead.
|
||||
|
||||
Strategies are stored in separate JavaScript files and loaded into the container at startup. Refer to [the Unleash Proxy documentation](../sdks/unleash-proxy.md) for a full overview of all the options.
|
||||
|
||||
1. **Create a strategies directory.** Create a directory that Docker has access to where you can store your strategies. The next steps assume you called it `strategies`
|
||||
2. **Initialize a node project** and **install the Unleash Client**:
|
||||
|
||||
``` shell
|
||||
npm init -y && \
|
||||
npm install unleash-client
|
||||
```
|
||||
|
||||
3. **Create a strategy file** and **implement your strategies**. Remember to **export your list of strategies**. The next steps will assume you called the file `timestamp.js`. An example implementation looks like this:
|
||||
|
||||
``` js
|
||||
const { Strategy } = require('unleash-client');
|
||||
|
||||
class TimeStampStrategy extends Strategy {
|
||||
constructor() {
|
||||
super('TimeStamp');
|
||||
}
|
||||
|
||||
isEnabled(parameters, context) {
|
||||
return Date.parse(parameters.enableAfter) > Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = [new TimeStampStrategy()]; // <- export strategies
|
||||
```
|
||||
|
||||
4. **Mount the strategies directory** and **point the [Unleash Proxy docker container](https://hub.docker.com/r/unleashorg/unleash-proxy) at your strategies file**. The highlighted lines below show the extra options you need to add. The following command assumes that your strategies directory is a direct subdirectory of your current working directory. Modify the rest of the command to suit your needs.
|
||||
|
||||
``` shell
|
||||
docker run --name unleash-proxy --pull=always \
|
||||
-e UNLEASH_PROXY_SECRETS=some-secret \
|
||||
-e UNLEASH_URL='http://unleash:4242/api/' \
|
||||
-e UNLEASH_API_TOKEN=${API_TOKEN} \
|
||||
# highlight-start
|
||||
-e UNLEASH_CUSTOM_STRATEGIES_FILE=/strategies/timestamp.js \
|
||||
--mount type=bind,source="$(pwd)"/strategies,target=/strategies \
|
||||
# highlight-end
|
||||
-p 3000:3000 --network unleash unleashorg/unleash-proxy
|
||||
```
|
@ -102,6 +102,42 @@ Keep-Alive: timeout=5
|
||||
|
||||
There are multiple more configuration options available. You find all [available options on github](https://github.com/Unleash/unleash-proxy#available-options).
|
||||
|
||||
## Custom activation strategies
|
||||
|
||||
The Unleash Proxy can load [custom activation strategies](../advanced/custom-activation-strategy.md) for front-end client SDKs ([Android](../sdks/android-proxy.md), [JavaScript](../sdks/proxy-javascript.md), [React](../sdks/proxy-react.md), [iOS](../sdks/proxy-ios.md)). For a step-by-step guide, refer to the [_how to use custom strategies_ guide](../how-to/how-to-use-custom-strategies.md#step-3-b).
|
||||
|
||||
To load custom strategies, use either of these two options:
|
||||
- the **`customStrategies`** option: use this if you're running the Unleash Proxy via Node directly.
|
||||
- the **`UNLEASH_CUSTOM_STRATEGIES_FILE`** environment variable: use this if you're running the proxy as a container.
|
||||
|
||||
Both options take a list of file paths to JavaScript files that export custom strategy implementations.
|
||||
|
||||
### Custom activation strategy files format
|
||||
|
||||
Each strategy file must export a list of instantiated strategies. A file can export as many strategies as you'd like.
|
||||
|
||||
Here's an example file that exports two custom strategies:
|
||||
|
||||
``` js
|
||||
const { Strategy } = require('unleash-client');
|
||||
|
||||
class MyCustomStrategy extends Strategy {
|
||||
// ... strategy implementation
|
||||
}
|
||||
|
||||
class MyOtherCustomStrategy extends Strategy {
|
||||
// ... strategy implementation
|
||||
}
|
||||
|
||||
// export strategies
|
||||
module.exports = [
|
||||
new MyCustomStrategy(),
|
||||
new MyOtherCustomStrategy()
|
||||
];
|
||||
```
|
||||
|
||||
Refer the [custom activation strategy documentation](../advanced/custom-activation-strategy.md#implementation) for more details on how to implement a custom activation strategy.
|
||||
|
||||
## Unleash Proxy API {#unleash-proxy-api}
|
||||
|
||||
The Unleash Proxy has a very simple API. It takes the [Unleash Context](../user_guide/unleash_context) as input and will return the feature toggles relevant for that specific context.
|
||||
|
@ -72,6 +72,7 @@ module.exports = {
|
||||
"How-to guides": [
|
||||
"how-to/how-to-add-strategy-constraints",
|
||||
"how-to/how-to-define-custom-context-fields",
|
||||
"how-to/how-to-use-custom-strategies",
|
||||
]
|
||||
},
|
||||
api: {
|
||||
|
BIN
website/static/img/custom-strategy-navigation.png
Normal file
BIN
website/static/img/custom-strategy-navigation.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 KiB |
BIN
website/static/img/strategy-parameters-ui-controls.png
Normal file
BIN
website/static/img/strategy-parameters-ui-controls.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 108 KiB |
Loading…
Reference in New Issue
Block a user