Skip to content

Commit

Permalink
docs(strats): separate reference and how-to
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasheartman committed Dec 22, 2021
1 parent caa5ae1 commit 9791783
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 53 deletions.
89 changes: 36 additions & 53 deletions website/docs/advanced/custom-activation-strategy.md
@@ -1,83 +1,66 @@
---
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).
:::

Custom activation strategies are ...
**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.

Must be implemented on the client.
Custom activation strategies work exactly like the built-in activation strategies when working in the admin UI.

## Example: TimeStamp Strategy {#example-timestamp-strategy}
## Definition

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.
![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)

### Define custom strategy {#define-custom-strategy}
You define custom activation strategies on your Unleash instance, either via the admin UI or via the API. A strategy contains:

First we need to "define" our new strategy. To add a new "Strategy", open the Strategies tab from the sidebar.
- 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.

![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)
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.

We name our strategy `TimeStamp` and add one required parameter of type string, which we call `enableAfter`.
### Parameters

### Use custom strategy {#use-custom-strategy}
![The strategy configuration screen for the custom "TimeStamp" strategy. The "enableAfter" field says "2021-12-25 00:00".](/img/timestamp_use_strategy.png)

After we have created the strategy definition, we can now decide to use that activation strategy for our feature toggle.
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.

![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)
If a strategy has a required parameter and you don't give it a value when creating the strategy, the strategy will not activate?

In the example we want to use our custom strategy for the feature toggle named `demo.TimeStampRollout`.
Each parameter consists of three parts:

### Client implementation {#client-implementation}
- 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.

All official client SDK's for Unleash provides abstractions for you to implement support for custom strategies.

> Before you have provided support for the custom strategy; the client will return false, because it does not understand the activation strategy.
#### Parameter types

In Node.js the implementation for the `TimeStampStrategy` would be:
Each parameter has one of five different parameter types. A parameter's type impacts the kind of controls shown in the admin UI and also changes how the value is represented in code.

```javascript
class TimeStampStrategy extends Strategy {
constructor() {
super('TimeStamp');
}
| type name | code representation[^1] | UI control |
|------------|-------------------------|--------------------------|
| string | `string` | A standard input field |
| percentage | `int` between 0 and 100 | A value slider |
| list | `string[]` | A multi-input text field |
| number | `int` | A numeric text field |
| boolean | `boolean` | An on/off toggle |

isEnabled(parameters, context) {
return Date.parse(parameters.enableAfter) < Date.now();
}
}
```

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.
![A strategy with five parameters, one of each type.](/img/strategy-parameters-ui-controls.png)

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.
## Implementation

We also have to remember to register the custom strategy when initializing the Unleash client. Full working code example:
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#client-implementation).

```javascript
const { Strategy, initialize, isEnabled } = require('unleash-client');
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).

class TimeStampStrategy extends Strategy {
constructor() {
super('TimeStamp');
}

isEnabled(parameters, context) {
return Date.parse(parameters.enableAfter) < Date.now();
}
}
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.

const instance = initialize({
url: 'http://unleash.herokuapp.com/api/',
appName: 'unleash-demo',
instanceId: '1',
strategies: [new TimeStampStrategy()],
});

instance.on('ready', () => {
setInterval(() => {
console.log(isEnabled('demo.TimeStampRollout'));
}, 1000);
});
```
[^1]: The exact type representation in code will vary depending on the language and its type system. See the docs for your client SDKs for specifics.
74 changes: 74 additions & 0 deletions website/docs/how-to/how-to-use-custom-strategies.md
@@ -0,0 +1,74 @@
---
title: How to use custom activation strategies
---

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.

## Define custom strategy {#define-custom-strategy}

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)

We name our strategy `TimeStamp` and add one required parameter of type string, which we call `enableAfter`.

## Use custom strategy {#use-custom-strategy}

After we have created the strategy definition, we can now decide to use that activation strategy for our feature toggle.

![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`.

## Client implementation {#client-implementation}

All official client SDK's for Unleash provides abstractions for you to implement support for custom strategies.

> 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:

```javascript
class TimeStampStrategy extends Strategy {
constructor() {
super('TimeStamp');
}

isEnabled(parameters, context) {
return Date.parse(parameters.enableAfter) < Date.now();
}
}
```

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.

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.

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');

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',
strategies: [new TimeStampStrategy()],
});

instance.on('ready', () => {
setInterval(() => {
console.log(isEnabled('demo.TimeStampRollout'));
}, 1000);
});
```
1 change: 1 addition & 0 deletions website/sidebars.js
Expand Up @@ -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: {
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9791783

Please sign in to comment.