diff --git a/README.md b/README.md index bb0b9ceb342b..37a25461dbed 100644 --- a/README.md +++ b/README.md @@ -135,14 +135,13 @@ Check out [the CONTRIBUTING.md file](./CONTRIBUTING.md) for contribution guideli ### Flexibility and adaptability -- Get an easy overview of all feature flags across all your environments, applications and services -- Use included [activation strategies](https://docs.getunleash.io/reference/activation-strategies) for most common use cases, or use a [custom activation strategy](https://docs.getunleash.io/reference/custom-activation-strategies) to support any need you might have -- Organise feature flags by [feature flag tags](https://docs.getunleash.io/reference/tags) +- Get an overview of all feature flags across all your environments, applications and services +- Targeted releases using [activation strategies](https://docs.getunleash.io/reference/activation-strategies) to enable and disable features for certain users or segments without having to redeploy your application. - [Canary releases / gradual rollouts](https://docs.getunleash.io/reference/activation-strategies#gradual-rollout) -- Targeted releases: release features to specific [users](https://docs.getunleash.io/reference/activation-strategies#userids), [IPs](https://docs.getunleash.io/reference/activation-strategies#ips), or [hostnames](https://docs.getunleash.io/reference/activation-strategies#hostnames) - [Kill switches](https://docs.getunleash.io/reference/feature-toggles#feature-flag-types) - [A/B testing](https://docs.getunleash.io/feature-flag-tutorials/use-cases/a-b-testing) - 2 [environments](https://docs.getunleash.io/reference/environments) +- Organize feature flags using [tags](https://docs.getunleash.io/reference/feature-toggles#tags) - Out-of-the-box integrations with popular tools ([Slack](https://docs.getunleash.io/addons/slack), [Microsoft Teams](https://docs.getunleash.io/addons/teams), [Datadog](https://docs.getunleash.io/addons/datadog)) + integrate with anything with [webhooks](https://docs.getunleash.io/addons/webhook) - [Dashboard for managing technical debt](https://docs.getunleash.io/reference/technical-debt) and [stale flags](https://docs.getunleash.io/reference/technical-debt#stale-and-potentially-stale-toggles) - API-first: _everything_ can be automated. No exceptions. @@ -166,7 +165,7 @@ If you're looking for one of the following features, please take a look at our [ - more environments - [feature flags project support](https://docs.getunleash.io/reference/projects) - [advanced segmentation](https://docs.getunleash.io/reference/segments) -- [additional strategy constraints](https://docs.getunleash.io/reference/strategy-constraints) +- [additional strategy constraints](https://docs.getunleash.io/reference/activation-strategies#constraints) - tighter security - more hosting options (we can even host it for you!) diff --git a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx index 53243fd74597..e09fd45a620c 100644 --- a/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx +++ b/frontend/src/component/common/ConstraintAccordion/ConstraintAccordionList/ConstraintAccordionList.tsx @@ -151,7 +151,7 @@ export const ConstraintAccordionList = forwardRef< > @@ -503,7 +503,7 @@ export const TOPICS: ITutorialTopic[] = [ <> diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/FeatureStrategyConstraintAccordionList/FeatureStrategyConstraintAccordionList.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/FeatureStrategyConstraintAccordionList/FeatureStrategyConstraintAccordionList.tsx index fa086a8ffef3..e7f79838eb26 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/FeatureStrategyConstraintAccordionList/FeatureStrategyConstraintAccordionList.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyConstraints/FeatureStrategyConstraintAccordionList/FeatureStrategyConstraintAccordionList.tsx @@ -80,7 +80,7 @@ export const FeatureStrategyConstraintAccordionList = forwardRef< feature flag for a subset of your users. Read more about constraints{' '} diff --git a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx index 57b2dd300c21..68ed174b75f2 100644 --- a/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx +++ b/frontend/src/component/feature/FeatureStrategy/FeatureStrategyForm/FeatureStrategyForm.tsx @@ -414,7 +414,7 @@ export const FeatureStrategyForm = ({ predefined strategies like Gradual rollout with{' '} ( Custom strategies are deprecated and may be removed in a future major version. Consider rewriting this strategy as a predefined strategy with{' '} diff --git a/frontend/src/component/splash/SplashPageOperators.tsx b/frontend/src/component/splash/SplashPageOperators.tsx index cbbc274a4629..3dd81aa6bf49 100644 --- a/frontend/src/component/splash/SplashPageOperators.tsx +++ b/frontend/src/component/splash/SplashPageOperators.tsx @@ -139,7 +139,7 @@ export const SplashPageOperators = () => {

diff --git a/frontend/src/component/strategies/CreateStrategy/CreateStrategy.tsx b/frontend/src/component/strategies/CreateStrategy/CreateStrategy.tsx index f890f3a0fae1..7faf4e2a397e 100644 --- a/frontend/src/component/strategies/CreateStrategy/CreateStrategy.tsx +++ b/frontend/src/component/strategies/CreateStrategy/CreateStrategy.tsx @@ -23,7 +23,7 @@ const CreateStrategyDeprecationWarning = () => ( Custom strategies are deprecated and may be removed in a future major release. We recommend using the predefined strategies like Gradual rollout with{' '} - + {' '} constraints {' '} diff --git a/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx b/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx index b5354a73820f..2f973d8553f2 100644 --- a/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx +++ b/frontend/src/component/strategies/StrategiesList/StrategiesList.tsx @@ -116,7 +116,9 @@ const StrategyDeprecationWarning = () => ( version. We recommend not using custom strategies going forward and instead using the predefined strategies with{' '} diff --git a/frontend/src/component/tags/CreateTagType/CreateTagType.tsx b/frontend/src/component/tags/CreateTagType/CreateTagType.tsx index 7f5d2ad9bd09..f2f505d7e957 100644 --- a/frontend/src/component/tags/CreateTagType/CreateTagType.tsx +++ b/frontend/src/component/tags/CreateTagType/CreateTagType.tsx @@ -61,7 +61,7 @@ const CreateTagType = () => { loading={loading} title='Create tag type' description='Tag types allow you to group tags together in the management UI' - documentationLink='https://docs.getunleash.io/reference/tags' + documentationLink='https://docs.getunleash.io/reference/feature-toggles#tags' documentationLinkLabel='Tags documentation' formatApiCode={formatApiCode} > diff --git a/src/lib/openapi/spec/addon-type-schema.ts b/src/lib/openapi/spec/addon-type-schema.ts index 96cf17e3be74..7acc30550b49 100644 --- a/src/lib/openapi/spec/addon-type-schema.ts +++ b/src/lib/openapi/spec/addon-type-schema.ts @@ -42,7 +42,7 @@ export const addonTypeSchema = { }, tagTypes: { type: 'array', - description: `A list of [Unleash tag types](https://docs.getunleash.io/reference/tags#tag-types) that this addon uses. These tags will be added to the Unleash instance when an addon of this type is created.`, + description: `A list of [Unleash tag types](https://docs.getunleash.io/reference/feature-toggles#tags) that this addon uses. These tags will be added to the Unleash instance when an addon of this type is created.`, example: [ { name: 'slack', diff --git a/src/lib/openapi/spec/constraint-schema.ts b/src/lib/openapi/spec/constraint-schema.ts index 07b2740f2cc5..974b17bfed18 100644 --- a/src/lib/openapi/spec/constraint-schema.ts +++ b/src/lib/openapi/spec/constraint-schema.ts @@ -5,7 +5,7 @@ export const constraintSchemaBase = { type: 'object', required: ['contextName', 'operator'], description: - 'A strategy constraint. For more information, refer to [the strategy constraint reference documentation](https://docs.getunleash.io/reference/strategy-constraints)', + 'A strategy constraint. For more information, refer to [the strategy constraint reference documentation](https://docs.getunleash.io/reference/activation-strategies#constraints)', properties: { contextName: { description: @@ -15,7 +15,7 @@ export const constraintSchemaBase = { }, operator: { description: - 'The operator to use when evaluating this constraint. For more information about the various operators, refer to [the strategy constraint operator documentation](https://docs.getunleash.io/reference/strategy-constraints#strategy-constraint-operators).', + 'The operator to use when evaluating this constraint. For more information about the various operators, refer to [the strategy constraint operator documentation](https://docs.getunleash.io/reference/activation-strategies#constraint-operators).', type: 'string', enum: ALL_OPERATORS, example: 'IN', diff --git a/src/lib/openapi/spec/create-feature-strategy-schema.ts b/src/lib/openapi/spec/create-feature-strategy-schema.ts index d3ad89c6c066..5dffc56bb665 100644 --- a/src/lib/openapi/spec/create-feature-strategy-schema.ts +++ b/src/lib/openapi/spec/create-feature-strategy-schema.ts @@ -35,7 +35,7 @@ export const createFeatureStrategySchema = { constraints: { type: 'array', description: - 'A list of the constraints attached to the strategy. See https://docs.getunleash.io/reference/strategy-constraints', + 'A list of the constraints attached to the strategy. See https://docs.getunleash.io/reference/activation-strategies#constraints', example: [ { values: ['1', '2'], diff --git a/src/lib/openapi/spec/create-tag-schema.ts b/src/lib/openapi/spec/create-tag-schema.ts index e9fd8e0832d3..d8f2f14e0998 100644 --- a/src/lib/openapi/spec/create-tag-schema.ts +++ b/src/lib/openapi/spec/create-tag-schema.ts @@ -6,7 +6,7 @@ export const createTagSchema = { ...tagSchema, $id: '#/components/schemas/createTagSchema', description: - 'Data used to create a new [tag](https://docs.getunleash.io/reference/tags)', + 'Data used to create a new [tag](https://docs.getunleash.io/reference/feature-toggles#tags)', properties: { ...tagSchema.properties, value: { diff --git a/src/lib/openapi/spec/feature-strategy-schema.ts b/src/lib/openapi/spec/feature-strategy-schema.ts index 97aed33307b6..7564daebab8e 100644 --- a/src/lib/openapi/spec/feature-strategy-schema.ts +++ b/src/lib/openapi/spec/feature-strategy-schema.ts @@ -55,7 +55,7 @@ export const featureStrategySchema = { constraints: { type: 'array', description: - 'A list of the constraints attached to the strategy. See https://docs.getunleash.io/reference/strategy-constraints', + 'A list of the constraints attached to the strategy. See https://docs.getunleash.io/reference/activation-strategies#constraints', items: { $ref: '#/components/schemas/constraintSchema', }, diff --git a/src/lib/openapi/spec/feature-tag-schema.ts b/src/lib/openapi/spec/feature-tag-schema.ts index f21aae94b0d4..58f2182138c9 100644 --- a/src/lib/openapi/spec/feature-tag-schema.ts +++ b/src/lib/openapi/spec/feature-tag-schema.ts @@ -16,7 +16,7 @@ export const featureTagSchema = { type: 'string', example: 'simple', description: - 'The [type](https://docs.getunleash.io/reference/tags#tag-types tag types) of the tag', + 'The [type](https://docs.getunleash.io/reference/feature-toggles#tags tag types) of the tag', }, tagValue: { type: 'string', @@ -27,7 +27,7 @@ export const featureTagSchema = { deprecated: true, type: 'string', description: - 'The [type](https://docs.getunleash.io/reference/tags#tag-types tag types) of the tag. This property is deprecated and will be removed in a future version of Unleash. Superseded by the `tagType` property.', + 'The [type](https://docs.getunleash.io/reference/feature-toggles#tags tag types) of the tag. This property is deprecated and will be removed in a future version of Unleash. Superseded by the `tagType` property.', }, value: { deprecated: true, diff --git a/src/lib/openapi/spec/tag-schema.ts b/src/lib/openapi/spec/tag-schema.ts index 060a80c09246..e08342f08088 100644 --- a/src/lib/openapi/spec/tag-schema.ts +++ b/src/lib/openapi/spec/tag-schema.ts @@ -5,7 +5,7 @@ export const tagSchema = { $id: '#/components/schemas/tagSchema', type: 'object', description: - 'Representation of a [tag](https://docs.getunleash.io/reference/tags)', + 'Representation of a [tag](https://docs.getunleash.io/reference/feature-toggles#tags)', additionalProperties: false, required: ['value', 'type'], properties: { @@ -21,7 +21,7 @@ export const tagSchema = { minLength: TAG_MIN_LENGTH, maxLength: TAG_MAX_LENGTH, description: - 'The [type](https://docs.getunleash.io/reference/tags#tag-types) of the tag', + 'The [type](https://docs.getunleash.io/reference/feature-toggles#tags) of the tag', example: 'simple', }, }, diff --git a/src/lib/openapi/spec/update-feature-strategy-schema.ts b/src/lib/openapi/spec/update-feature-strategy-schema.ts index 11ab541520d8..52863c5e6f81 100644 --- a/src/lib/openapi/spec/update-feature-strategy-schema.ts +++ b/src/lib/openapi/spec/update-feature-strategy-schema.ts @@ -22,7 +22,7 @@ export const updateFeatureStrategySchema = { $ref: '#/components/schemas/constraintSchema', }, description: - 'A list of the constraints attached to the strategy. See https://docs.getunleash.io/reference/strategy-constraints', + 'A list of the constraints attached to the strategy. See https://docs.getunleash.io/reference/activation-strategies#constraints', }, title: { type: 'string', diff --git a/src/lib/openapi/util/openapi-tags.ts b/src/lib/openapi/util/openapi-tags.ts index a976d8c653b0..b9613b12cd10 100644 --- a/src/lib/openapi/util/openapi-tags.ts +++ b/src/lib/openapi/util/openapi-tags.ts @@ -136,7 +136,7 @@ const OPENAPI_TAGS = [ { name: 'Tags', description: - 'Create, update, and delete [tags and tag types](https://docs.getunleash.io/reference/tags).', + 'Create, update, and delete [tags and tag types](https://docs.getunleash.io/reference/feature-toggles#tags).', }, { name: 'Telemetry', diff --git a/src/lib/routes/admin-api/context.ts b/src/lib/routes/admin-api/context.ts index 7c87787c66e8..6d50cb539247 100644 --- a/src/lib/routes/admin-api/context.ts +++ b/src/lib/routes/admin-api/context.ts @@ -73,7 +73,7 @@ export class ContextController extends Controller { tags: ['Context'], summary: 'Gets configured context fields', description: - 'Returns all configured [Context fields](https://docs.getunleash.io/how-to/how-to-define-custom-context-fields) that have been created.', + 'Returns all configured [Context fields](https://docs.getunleash.io/reference/unleash-context) that have been created.', operationId: 'getContextFields', responses: { 200: createResponseSchema('contextFieldsSchema'), diff --git a/website/docs/feature-flag-tutorials/django/django-examples.md b/website/docs/feature-flag-tutorials/django/django-examples.md index 5bf0fc8fd5b9..68654a687a51 100644 --- a/website/docs/feature-flag-tutorials/django/django-examples.md +++ b/website/docs/feature-flag-tutorials/django/django-examples.md @@ -96,7 +96,7 @@ Unleash has a few ways to help manage canary deployments for Django apps at scal - Using a [gradual rollout](/reference/activation-strategies#gradual-rollout) (which we [implemented in a previous section](#gradual-rollouts-for-python-apps)) would be a simple use case but would reduce the amount of control you have over who gets the new feature. -- Using either [constraints](/reference/strategy-constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout +- Using either [constraints](/reference/activation-strategies#constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout - [Strategy variants](/reference/strategy-variants) are used to do the same canary deployment, but can be scaled to more _advanced_ cases. For example, if you have 2+ new features and are testing to see if they are better than the old one, you can use variants to split your population of users and conduct an A/B test with them. @@ -178,7 +178,7 @@ print(response.text) Check out our [API docs on updating flag strategies](/reference/api/unleash/update-feature-strategy) to learn more. -Read our documentation for more context on [strategy constraint configurations](/reference/strategy-constraints) and use cases. +Read our documentation for more context on [strategy constraint configurations](/reference/activation-strategies#constraints) and use cases. ## Server-side A/B Testing in Django diff --git a/website/docs/feature-flag-tutorials/dotnet/dotnet-examples.md b/website/docs/feature-flag-tutorials/dotnet/dotnet-examples.md index e6c86e0115e3..0989200bb2e7 100644 --- a/website/docs/feature-flag-tutorials/dotnet/dotnet-examples.md +++ b/website/docs/feature-flag-tutorials/dotnet/dotnet-examples.md @@ -91,7 +91,7 @@ Unleash has a few ways to help manage canary deployments for .NET apps at scale: - Using a [gradual rollout](/reference/activation-strategies#gradual-rollout) (which we [implemented in a previous section](#gradual-rollouts-for-net-apps)) would be a simple use case but would reduce the amount of control you have over who gets the new feature. -- Using either [constraints](/reference/strategy-constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout +- Using either [constraints](/reference/activation-strategies#constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout - [Strategy variants](/reference/strategy-variants) are used to do the same canary deployment, but can be scaled to more _advanced_ cases. For example, if you have 2+ new features and are testing to see if they are better than the old one, you can use variants to split your population of users and conduct an A/B test with them. @@ -172,7 +172,7 @@ Console.WriteLine(responseBody); Check out our [API docs on updating flag strategies](/reference/api/unleash/update-feature-strategy) to learn more. -Read our documentation for more context on [strategy constraint configurations](/reference/strategy-constraints) and use cases. +Read our documentation for more context on [strategy constraint configurations](/reference/activation-strategies#constraints) and use cases. ## Server-side A/B Testing in .NET diff --git a/website/docs/feature-flag-tutorials/ios/examples.md b/website/docs/feature-flag-tutorials/ios/examples.md index 4712b2c9c75a..0c36e72fd170 100644 --- a/website/docs/feature-flag-tutorials/ios/examples.md +++ b/website/docs/feature-flag-tutorials/ios/examples.md @@ -83,7 +83,7 @@ Unleash has a few ways to help manage canary deployments for iOS apps at scale: - Using a [gradual rollout](/reference/activation-strategies#gradual-rollout) (which we [implemented in a previous section](#gradual-rollouts-for-ios-apps)) would be a simple use case but would reduce the amount of control you have over who gets the new feature. -- Using either [constraints](/reference/strategy-constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout +- Using either [constraints](/reference/activation-strategies#constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout - [Strategy variants](/reference/strategy-variants) are used to do the same canary deployment, but can be scaled to more _advanced_ cases. For example, if you have 2+ new features and are testing to see if they are better than the old one, you can use variants to split your population of users and conduct an A/B test with them. @@ -143,7 +143,7 @@ curl --location --request PUT 'http://localhost:4242/api/admin/projects/default/ }' ``` -Read our documentation for more context on the robustness of [strategy constraint configurations](/reference/strategy-constraints) and use cases. +Read our documentation for more context on the robustness of [strategy constraint configurations](/reference/activation-strategies#constraints) and use cases. ## A/B Testing in iOS diff --git a/website/docs/feature-flag-tutorials/java/spring-boot-examples.md b/website/docs/feature-flag-tutorials/java/spring-boot-examples.md index 1dbb60368699..8a576211d81b 100644 --- a/website/docs/feature-flag-tutorials/java/spring-boot-examples.md +++ b/website/docs/feature-flag-tutorials/java/spring-boot-examples.md @@ -79,7 +79,7 @@ Unleash has a few ways to help manage canary deployments for Java apps at scale: - Using a [gradual rollout](/reference/activation-strategies#gradual-rollout) (which we [implemented in a previous section](#gradual-rollouts-for-java-spring-boot-apps)) would be a simple use case but would reduce the amount of control you have over who gets the new feature. -- Using either [constraints](/reference/strategy-constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout +- Using either [constraints](/reference/activation-strategies#constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout - [Strategy variants](/reference/strategy-variants) are used to do the same canary deployment, but can be scaled to more _advanced_ cases. For example, if you have 2+ new features and are testing to see if they are better than the old one, you can use variants to split your population of users and conduct an A/B test with them. @@ -134,7 +134,7 @@ Response response = client.newCall(request).execute(); Check out our [API docs on updating flag strategies](/reference/api/unleash/update-feature-strategy) to learn more. -Read our documentation for more context on [strategy constraint configurations](/reference/strategy-constraints) and use cases. +Read our documentation for more context on [strategy constraint configurations](/reference/activation-strategies#constraints) and use cases. ## Server-side A/B Testing in Java Spring Boot diff --git a/website/docs/feature-flag-tutorials/python/examples.md b/website/docs/feature-flag-tutorials/python/examples.md index eb974ec4ad48..a141aee1dea1 100644 --- a/website/docs/feature-flag-tutorials/python/examples.md +++ b/website/docs/feature-flag-tutorials/python/examples.md @@ -95,7 +95,7 @@ Unleash has a few ways to help manage canary deployments for Python apps at scal - Using a [gradual rollout](/reference/activation-strategies#gradual-rollout) (which we [implemented in a previous section](#gradual-rollouts-for-python-apps)) would be a simple use case but would reduce the amount of control you have over who gets the new feature. -- Using either [constraints](/reference/strategy-constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout +- Using either [constraints](/reference/activation-strategies#constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout - [Strategy variants](/reference/strategy-variants) are used to do the same canary deployment, but can be scaled to more _advanced_ cases. For example, if you have 2+ new features and are testing to see if they are better than the old one, you can use variants to split your population of users and conduct an A/B test with them. @@ -177,7 +177,7 @@ print(response.text) Check out our [API docs on updating flag strategies](/reference/api/unleash/update-feature-strategy) to learn more. -Read our documentation for more context on [strategy constraint configurations](/reference/strategy-constraints) and use cases. +Read our documentation for more context on [strategy constraint configurations](/reference/activation-strategies#constraints) and use cases. ## Server-side A/B Testing in Python diff --git a/website/docs/feature-flag-tutorials/rails/rails-examples.md b/website/docs/feature-flag-tutorials/rails/rails-examples.md index fa6808c214e0..87ff94d9fc52 100644 --- a/website/docs/feature-flag-tutorials/rails/rails-examples.md +++ b/website/docs/feature-flag-tutorials/rails/rails-examples.md @@ -95,7 +95,7 @@ Unleash has a few ways to help manage canary deployments for Ruby apps at scale: - Using a [gradual rollout](/reference/activation-strategies#gradual-rollout) (which we [implemented in a previous section](#gradual-rollouts-for-ruby-apps)) would be a simple use case but would reduce the amount of control you have over who gets the new feature. -- Using either [constraints](/reference/strategy-constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout +- Using either [constraints](/reference/activation-strategies#constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout - [Strategy variants](/reference/strategy-variants) are used to do the same canary deployment, but can be scaled to more _advanced_ cases. For example, if you have 2+ new features and are testing to see if they are better than the old one, you can use variants to split your population of users and conduct an A/B test with them. @@ -171,7 +171,7 @@ puts response.body Check out our [API docs on updating flag strategies](/reference/api/unleash/update-feature-strategy) to learn more. -Read our documentation for more context on [strategy constraint configurations](/reference/strategy-constraints) and use cases. +Read our documentation for more context on [strategy constraint configurations](/reference/activation-strategies#constraints) and use cases. ## Server-side A/B Testing in Rails diff --git a/website/docs/feature-flag-tutorials/react/examples.md b/website/docs/feature-flag-tutorials/react/examples.md index 4148f44bd6a5..aa99258cfaaf 100644 --- a/website/docs/feature-flag-tutorials/react/examples.md +++ b/website/docs/feature-flag-tutorials/react/examples.md @@ -98,7 +98,7 @@ Unleash has a few ways to help manage canary deployments for React apps at scale - Using a [gradual rollout](/reference/activation-strategies#gradual-rollout) (which we [implemented in a previous section](#gradual-rollouts-for-react-apps)) would be a simple use case but would reduce the amount of control you have over who gets the new feature. -- Using either [constraints](/reference/strategy-constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout +- Using either [constraints](/reference/activation-strategies#constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout - [Strategy variants](/reference/strategy-variants) are used to do the same canary deployment, but can be scaled to more _advanced_ cases. For example, if you have 2+ new features and are testing to see if they are better than the old one, you can use variants to split your population of users and conduct an A/B test with them. @@ -162,7 +162,7 @@ curl --location --request PUT 'http://localhost:4242/api/admin/projects/default/ }' ``` -Read our documentation for more context on the robustness of [strategy constraint configurations](/reference/strategy-constraints) and use cases. +Read our documentation for more context on the robustness of [strategy constraint configurations](/reference/activation-strategies#constraints) and use cases. ## A/B Testing in React diff --git a/website/docs/feature-flag-tutorials/ruby/ruby-examples.md b/website/docs/feature-flag-tutorials/ruby/ruby-examples.md index 3ba6fa36d64f..36cea30f93be 100644 --- a/website/docs/feature-flag-tutorials/ruby/ruby-examples.md +++ b/website/docs/feature-flag-tutorials/ruby/ruby-examples.md @@ -94,7 +94,7 @@ Unleash has a few ways to help manage canary deployments for Ruby apps at scale: - Using a [gradual rollout](/reference/activation-strategies#gradual-rollout) (which we [implemented in a previous section](#gradual-rollouts-for-ruby-apps)) would be a simple use case but would reduce the amount of control you have over who gets the new feature. -- Using either [constraints](/reference/strategy-constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout +- Using either [constraints](/reference/activation-strategies#constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout - [Strategy variants](/reference/strategy-variants) are used to do the same canary deployment, but can be scaled to more _advanced_ cases. For example, if you have 2+ new features and are testing to see if they are better than the old one, you can use variants to split your population of users and conduct an A/B test with them. @@ -170,7 +170,7 @@ puts response.body Check out our [API docs on updating flag strategies](/reference/api/unleash/update-feature-strategy) to learn more. -Read our documentation for more context on [strategy constraint configurations](/reference/strategy-constraints) and use cases. +Read our documentation for more context on [strategy constraint configurations](/reference/activation-strategies#constraints) and use cases. ## Server-side A/B Testing in Ruby diff --git a/website/docs/feature-flag-tutorials/rust/rust-examples.md b/website/docs/feature-flag-tutorials/rust/rust-examples.md index c956c9e322c3..9444057a78c5 100644 --- a/website/docs/feature-flag-tutorials/rust/rust-examples.md +++ b/website/docs/feature-flag-tutorials/rust/rust-examples.md @@ -115,7 +115,7 @@ Unleash has a few ways to help manage canary deployments for Rust apps: - Using a [gradual rollout](/reference/activation-strategies#gradual-rollout) (which we [implemented in a previous section](#gradual-rollouts-for-rust-apps)) would be a simple use case but would reduce the amount of control you have over who gets the new feature. -- Using either [constraints](/reference/strategy-constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout +- Using either [constraints](/reference/activation-strategies#constraints) or [segments](/reference/segments) (which are a collection of constraints) for a subset of your users to get the new feature vs. the old feature, for _more_ control than a gradual rollout - [Strategy variants](/reference/strategy-variants) are used to do the same canary deployment, but can be scaled to more _advanced_ cases. For example, if you have 2+ new features and are testing to see if they are better than the old one, you can use variants to split your population of users and conduct an A/B test with them. @@ -209,7 +209,7 @@ fn main() -> Result<(), Box> { Check out our [API docs on updating flag strategies](/reference/api/unleash/update-feature-strategy) to learn more. -Read our documentation for more context on [strategy constraint configurations](/reference/strategy-constraints) and use cases. +Read our documentation for more context on [strategy constraint configurations](/reference/activation-strategies#constraints) and use cases. ## Server-side A/B Testing in Rust diff --git a/website/docs/feature-flag-tutorials/use-cases/a-b-testing.md b/website/docs/feature-flag-tutorials/use-cases/a-b-testing.md index 3fa0136fc5aa..877ab50a8b25 100644 --- a/website/docs/feature-flag-tutorials/use-cases/a-b-testing.md +++ b/website/docs/feature-flag-tutorials/use-cases/a-b-testing.md @@ -69,7 +69,7 @@ Next, configure the rollout percentage so only a certain portion of your users a There are two more advanced extensions of a default strategy that you will see available to customize in the form: - [Strategy variants](/reference/strategy-variants) -- [Strategy constraints](/reference/strategy-constraints) +- [Strategy constraints](/reference/activation-strategies#constraints) With strategy variants and constraints, you can extend your overall strategy. They help you define more granular conditions for your feature beyond the rollout percentage. We recommend using strategy variants to configure an A/B test. diff --git a/website/docs/feature-flag-tutorials/use-cases/gradual-rollout.md b/website/docs/feature-flag-tutorials/use-cases/gradual-rollout.md index 4e660492af32..8b9efe6824b0 100644 --- a/website/docs/feature-flag-tutorials/use-cases/gradual-rollout.md +++ b/website/docs/feature-flag-tutorials/use-cases/gradual-rollout.md @@ -66,7 +66,7 @@ You can configure your gradual rollout strategy using the following parameters i There are two more advanced extensions of the gradual rollout strategy that you can customize in the gradual rollout form: -- [Strategy Constraints](/reference/strategy-constraints) +- [Strategy Constraints](/reference/activation-strategies#constraints) - [Strategy Variants](/reference/strategy-variants) Constraints and variants are not required for a gradual rollout. These additional customizations can be built on top of the overall rollout strategy should you need more granular conditions for your feature beyond the rollout percentage. @@ -77,7 +77,7 @@ For gradual rollouts, _strategy constraints_ are most applicable for more granul ## Applying Strategy Constraints -When utilizing an activation strategy such as a gradual rollout, it may be necessary to further define which subset of users get access to a feature and when the rollout takes place, depending on the complexity of your use case. Unleash provides [strategy constraints](/reference/strategy-constraints) as a way to fine-tune conditions under which a feature flag is evaluated. +When utilizing an activation strategy such as a gradual rollout, it may be necessary to further define which subset of users get access to a feature and when the rollout takes place, depending on the complexity of your use case. Unleash provides [strategy constraints](/reference/activation-strategies#constraints) as a way to fine-tune conditions under which a feature flag is evaluated. ![This diagram breaks down how strategy constraints sit on top activation strategies for flags in Unleash.](/img/tutorial-building-blocks-strategy-constraints.png) @@ -91,20 +91,16 @@ Within a gradual rollout activation strategy, you can use strategy constraints t ![You can configure your strategy constraints in the gradual rollout form.](/img/tutorial-constraints-form.png) -Add constraints to refine the rollout based on user attributes, segments, or conditions. +Add [constraints](/reference/activation-strategies#constraints) to refine the rollout based on user attributes, segments, or conditions. -To learn more, read our docs on: - -1. [Strategy constraints](/reference/strategy-constraints) -2. [How to add strategy constraints](/how-to/how-to-add-strategy-constraints) ### Define Custom Context Fields for Strategy Constraints -If you want to create new types of constraints that are not built into Unleash, you can create custom context fields and apply them to your constraints. Follow our [how-to guide on creating custom context fields](/how-to/how-to-define-custom-context-fields) to use in your gradual rollout for more advanced use cases. +If you want to create new types of constraints that are not built into Unleash, you can create [custom context fields](/reference/unleash-context#custom-context-fields) to use in your gradual rollout for more advanced use cases. ## Leveraging Segments -A [segment](/reference/segments) is a reusable collection of [strategy constraints](/reference/strategy-constraints). Like with strategy constraints, you apply segments to feature flag activation strategies. +A [segment](/reference/segments) is a reusable collection of [strategy constraints](/reference/activation-strategies#constraints). Like with strategy constraints, you apply segments to feature flag activation strategies. You can apply the same segment to multiple activation strategies. If you update the segment, the changes will affect every strategy that uses that segment. diff --git a/website/docs/feature-flag-tutorials/use-cases/trunk-based-development.md b/website/docs/feature-flag-tutorials/use-cases/trunk-based-development.md index d657a9d18147..95081dccba99 100644 --- a/website/docs/feature-flag-tutorials/use-cases/trunk-based-development.md +++ b/website/docs/feature-flag-tutorials/use-cases/trunk-based-development.md @@ -222,7 +222,7 @@ Develop clear and [consistent naming patterns](/reference/feature-toggles#set-a- ### Leverage tagging and flag descriptions -In addition to meaningful names, apply relevant [tags](/reference/tags) and descriptions to your feature flags in Unleash. This metadata can include information such as: +In addition to meaningful names, apply relevant [tags](/reference/feature-toggles#tags) and descriptions to your feature flags in Unleash. This metadata can include information such as: - The team or product area responsible for the flag - The release timeline or planned retirement date @@ -278,7 +278,7 @@ To target users accordingly, let's create an [activation strategy](/reference/ac Next, let's create a new activation strategy and configure the rollout percentage so only a certain portion of your users are targeted. For example, you can adjust the dial so that 35% of all users are targeted. The remaining percentage of users will not experience any variation of the new feature. Adjust the rollout dial to set the percentage of users the feature targets, or keep it at 100% to target all users. -To define more granular conditions for your feature beyond the rollout percentage, you can use [strategy variants](/reference/strategy-variants) and [constraints](/reference/strategy-constraints). +To define more granular conditions for your feature beyond the rollout percentage, you can use [strategy variants](/reference/strategy-variants) and [constraints](/reference/activation-strategies#constraints). ## Simplify rollbacks diff --git a/website/docs/how-to/how-to-add-strategy-constraints.md b/website/docs/how-to/how-to-add-strategy-constraints.md deleted file mode 100644 index 4c472c8fcd96..000000000000 --- a/website/docs/how-to/how-to-add-strategy-constraints.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: How to add strategy constraints ---- - -:::note Availability - -**Version**: `4.16+` - -::: - -This guide shows you how to add [strategy constraints](../reference/strategy-constraints) to your feature flags using the Admin UI. For information on how to interact with strategy constraints from an [Unleash client SDK](../reference/sdks), visit the specific SDK's documentation or see [the relevant section in the strategy constraints documentation](../reference/strategy-constraints#sdks). - -## Prerequisites - -You'll need to have an existing feature flag with a defined strategy to add a constraint. The rest of this guide assumes you have a specific strategy that you're working with. - -## Step 1: Open the constraints menu {#step-1} - -On the strategy you're working with, find and select the "edit strategy" button. - -![A feature flag with one strategy. The "edit strategy" button is highlighted.](/img/create-toggle-edit-strategy.png) - -On the "edit strategy" screen, select the "add constraint" button to open the constraints menu. - -![A feature flag strategy view showing a button labeled with add constraints.](/img/add-constraint.png) - -## Step 2: Add and configure the constraint {#step-2} - -Refer to [the _constraint structure_ section of the strategy constraints reference](../reference/strategy-constraints#constraint-structure) for a thorough explanation of the constraint fields. - -1. From the "Context Field" dropdown, **select the context field** you would like to constrain the strategy on and **choose the [constraint operator](../reference/strategy-constraints#strategy-constraint-operators)** you want. -2. **Define the values** to use for this constraint. The operator you selected decides whether you can define one or multiple values and what format they can have. -3. **Save the constraint** first. - -![A strategy constraint form with a constraint set to "useid". The "values" input is a text input containing the values "41", "932", "822".](/img/constraints-add-to-strategy.png) - -## Step 3: Save the strategy {#step-3} - -![A feature flag strategy view showing a button at the end of the form labeled with save strategy.](/img/constraints-save-strategy.png) - -## How to update existing constraints - -To update an existing constraint, find the constraint in the "edit strategy" screen and use the constraint's "edit" button. - -![A strategy form showing an existing constraint with existing values and 2 buttons, the "edit" button is highlighted.](/img/constraints-edit.png) diff --git a/website/docs/how-to/how-to-create-feature-toggles.md b/website/docs/how-to/how-to-create-feature-toggles.md index 1d283f85111a..f6b8b8d6dd42 100644 --- a/website/docs/how-to/how-to-create-feature-toggles.md +++ b/website/docs/how-to/how-to-create-feature-toggles.md @@ -81,7 +81,7 @@ These optional steps allow you to further configure your feature flags to add op ### Add constraints and segmentation -Constraints and segmentation allow you to set filters on your strategies, so that they will only be evaluated for users and applications that match the specified preconditions. Refer to the [strategy constraints](../reference/strategy-constraints) and [segments reference documentation](../reference/segments) for more information. +Constraints and segmentation allow you to set filters on your strategies, so that they will only be evaluated for users and applications that match the specified preconditions. Refer to the [strategy constraints](../reference/activation-strategies#constraints) and [segments reference documentation](../reference/segments) for more information. To add constraints and segmentation, use the "edit strategy" button for the desired strategy. diff --git a/website/docs/how-to/how-to-define-custom-context-fields.md b/website/docs/how-to/how-to-define-custom-context-fields.md deleted file mode 100644 index 8d187c12beb9..000000000000 --- a/website/docs/how-to/how-to-define-custom-context-fields.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: How to define custom context fields ---- - -:::note Availability - -**Version**: `4.16+` - -::: - -This guide shows you how to create [custom context field for the Unleash Context](../reference/unleash-context#custom-context-fields). You can use custom context fields for [strategy constraints](../reference/strategy-constraints) and for [custom stickiness calculations](../reference/stickiness#custom-stickiness). If there are [standard Unleash Context fields](../reference/unleash-context#structure) missing from the context fields page, you can use the same steps to add them too. - -## Step 1: Navigate to the context field creation form {#step-1-navigate-to-context-fields} - -In the Unleash Admin UI, navigate to the _context fields_ page: -1. Click the "Configure" button in the top menu to open the configuration dropdown menu. -2. Click the "Context fields" menu item. - - ![A visual representation of the tutorial steps described in the preceding paragraph, showing the interaction points in the admin UI in order.](/img/context-fields.png) - -3. On the context fields page, click the "add new context field" button. - - ![The "context fields" page with the "add new context field" button highlighted.]( /img/context-field-create-button.png) - -## Step 2: Define the new context field {#step-2-define-new-context-field} - -Define the custom context field by filling out the form. You must at least give the field a unique _name_. Everything else is optional. Refer to the [custom context field reference guide](../reference/unleash-context#custom-context-fields) for a full overview of the parameters and their functions and requirements. - -When you are satisfied with the context field's values, use the "create" button to submit the form and save the context field. - -![A "create context field" form. It contains data for a custom context field called "region". Its description is "allows you to constrain on specific regions" and its legal values are "Africa", "Asia", "Europe", and "North America". Its custom stickiness value is not shown.](/img/new_context_field.png) diff --git a/website/docs/how-to/how-to-environment-import-export.mdx b/website/docs/how-to/how-to-environment-import-export.mdx index b358be382c55..6300720d7aeb 100644 --- a/website/docs/how-to/how-to-environment-import-export.mdx +++ b/website/docs/how-to/how-to-environment-import-export.mdx @@ -28,18 +28,18 @@ When you export features, the export will contain both feature-specific configur On the project-level these items are exported: * [the feature itself](/reference/feature-toggles) -* [feature tags](/reference/tags) +* [feature tags](/reference/feature-toggles#tags) * [feature dependencies](/reference/feature-toggles#feature-flag-dependencies) On the environment-level, these items are exported for the chosen environment: -* [activation strategies](/reference/activation-strategies) including [constraints](/reference/strategy-constraints) and references to [segments](/reference/segments) +* [activation strategies](/reference/activation-strategies) including [constraints](/reference/activation-strategies#constraints) and references to [segments](/reference/segments) * [variants](/reference/feature-toggle-variants) * enabled/disabled Additionally, these global configuration items are exported: * [custom context fields](/reference/unleash-context#custom-context-fields) -* [feature tag types](/reference/tags#tag-types) +* [feature tag types](/reference/feature-toggles#tags) Importantly, while references to [segments](/reference/segments) are exported, the segments themselves are **not** exported. Consult the [import requirements](#import-requirements) section for more information. @@ -111,6 +111,10 @@ If you permanently delete the archived `feature-a` from the target instance, the #### Custom strategies +:::caution +[Custom activation strategies](/reference/custom-activation-strategies) are deprecated. Please use the [default activation strategy](/reference/activation-strategies) with constraints. +::: + Unleash will verify that any custom strategies you are trying to import have already been defined on the target instance. However, it only does this verification by name. It does **not** validate that the definitions are otherwise the same or that they have the same [configuration parameters](/reference/custom-activation-strategies.md#parameters). ### Required permissions diff --git a/website/docs/how-to/how-to-schedule-feature-releases.mdx b/website/docs/how-to/how-to-schedule-feature-releases.mdx index be41fead3312..edbd4028230d 100644 --- a/website/docs/how-to/how-to-schedule-feature-releases.mdx +++ b/website/docs/how-to/how-to-schedule-feature-releases.mdx @@ -3,8 +3,10 @@ title: How to schedule feature releases --- import ApiRequest from '@site/src/components/ApiRequest' -:::info Placeholders -Placeholders in the code samples below are delimited by angle brackets (i.e. ``). You will need to replace them with the values that are correct in _your_ situation for the code samples to run properly. +:::note Availability + +**Version**: `4.16+` + ::: There's a whole host of reasons why you may want to schedule the release of a feature, such as: @@ -12,9 +14,6 @@ There's a whole host of reasons why you may want to schedule the release of a fe - **to make a feature available only up until a specific moment** (for a contest cutoff, for instance) - **to make a feature available during a limited period** (for a 24 hour flash sale, for instance) -Depending on which version of Unleash you are using, there are two ways to schedule a feature release. If you are using [Pro](/availability#plans) or [Enterprise](https://www.getunleash.io/pricing) version 4.9 or later, you can use [strategy constraints](#schedule-feature-releases-with-strategy-constraints). -Otherwise, you can use [custom activation strategies](#schedule-feature-releases-with-custom-activation-strategies). - In this guide we'll schedule a feature for release at some point in time. The exact same logic applies if you want to make a feature available until some point in the future. Finally, if you want to only make a feature available during a limited time period, you can easily combine the two options. ## Prerequisites @@ -24,9 +23,9 @@ This guide assumes that you've got the following: - a running instance of Unleash and connected clients (where applicable) - an existing feature flag that you want to schedule the release for -## Schedule feature releases with strategy constraints {#strategy-constraints} +## Schedule feature releases with strategy constraints -[Strategy constraints](../reference/strategy-constraints#date-and-time-operators) are the easiest way to schedule feature releases ([as long as your SDKs are up to date](../reference/strategy-constraints#incompatibilities)). You can use this approach with _any_ strategy you want. The strategies will work just as they normally do, they just won't become active until the specified time. For example: with the standard strategy, the feature would become available to all your users at the specified time; with a gradual rollout, the rollout would start at the specified time. +[Strategy constraints](../reference/activation-strategies#date-and-time-operators) are the easiest way to schedule feature releases ([as long as your SDKs are up to date](../reference/activation-strategies#client-side-implementation)). You can use this approach with _any_ strategy you want. The strategies will work just as they normally do, they just won't become active until the specified time. For example: with the standard strategy, the feature would become available to all your users at the specified time; with a gradual rollout, the rollout would start at the specified time. ### Step 1: Add an activation strategy with a date-based constraint @@ -57,27 +56,4 @@ The `"constraint"` object should have the same format as described in the code s ] }} url="api/admin/projects//features/environments//strategies" title="Add a feature activation strategy with a scheduled activation time."/> -The `"operator"` property in the code sample can be replaced with [any of the other date and time-based operators](../reference/strategy-constraints#date-and-time-operators) according to your needs. - -## Schedule feature releases with custom activation strategies {#custom-activation-strategies} - -To schedule feature releases without using strategy constraints, you can use custom activation strategies. This requires defining a custom strategy and then implementing that strategy in your SDKs. For detailed instructions on how to do either of these things, refer to their respective how-to guides: -- [How to _define_ custom strategies](../how-to/how-to-use-custom-strategies#step-1) -- [How to _implement_ custom strategies](../how-to/how-to-use-custom-strategies#step-3) - -### Step 1: Define and apply a custom activation strategy - -**Define a strategy** that takes a parameter that tells it when to activate (visit [the custom activation strategy reference documentation](../reference/custom-activation-strategies#definition) for full details on definitions): - -1. Give the strategy a name. We'll use `enableAfter`. -2. Give the strategy a required string parameter where the user can enter the time at which the feature should activate. Be sure to describe the format that the user must adhere to. -3. Save the strategy - -[**Apply the strategy** to the feature flag](../how-to/how-to-use-custom-strategies#step-2) you want to schedule. - - -![A custom activation strategy definition for a strategy called `enableAfter`. It takes a required parameter called `start time`: a string in a date format.](/img/custom-strategy-enable-after.png) - -### Step 2: Implement the custom activation strategy in your clients - -In each of the client SDKs that will interact with your feature, implement the strategy ([the implementation how-to guide](../how-to/how-to-use-custom-strategies#step-3) has steps for all SDK types). \ No newline at end of file +The `"operator"` property in the code sample can be replaced with [any of the other date and time-based operators](../reference/activation-strategies#date-and-time-operators) according to your needs. \ No newline at end of file diff --git a/website/docs/how-to/how-to-use-custom-strategies.md b/website/docs/how-to/how-to-use-custom-strategies.md deleted file mode 100644 index b9fcd30a49d8..000000000000 --- a/website/docs/how-to/how-to-use-custom-strategies.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -title: How to use custom activation strategies ---- - -:::tip - -Use custom activation strategies only for cases where [strategy constraints](https://docs.getunleash.io/reference/strategy-constraints) don't give you enough control. - -The downside of using a custom activation strategy instead of constraints is that you need to distribute the code of your strategy with Unleash client SDK while on the other hand, [strategy constraints](https://docs.getunleash.io/reference/strategy-constraints) work without any extra code or maintenance. -::: - - -This guide takes you through how to use [custom activation strategies](../reference/custom-activation-strategies) with Unleash. We'll go through how you define a custom strategy in the admin UI, how you add it to a flag, and how you'd implement it in a [client SDK](../reference/sdks). - -In this example we want to define an activation strategy offers a scheduled release of a feature flag. This means that we want the feature flag 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](../reference/custom-activation-strategies#definition) for a full list of options. - - ![A strategy creation form. It has fields labeled "strategy name" — "TimeStamp" — and "description" — "activate flag 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 flag {#step-2} - -**Navigate to your feature flag** 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](../reference/sdks/android-proxy), [JavaScript](../reference/sdks/javascript-browser)), [React](../reference/sdks/react), [iOS](../reference/sdks/ios-proxy)), 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](../reference/sdks). 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](../reference/sdks/node). - - ```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: 'https://unleash.example.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 SDKs don't evaluate strategies directly, so you need to implement the **custom strategy in the [Unleash Proxy](../reference/unleash-proxy)**. Depending on how you run the Unleash Proxy, follow one of the below series of steps: - -- If you're running the Unleash Proxy as a Docker container, refer to the [steps for using a containerized Proxy](#step-3-b-docker). -- If you're using the Unleash Proxy via Node.js, refer to the [steps for using custom strategies via Node.js](#step-3-b-node). - -#### With a containerized proxy {#step-3-b-docker} - -Strategies are stored in separate JavaScript files and loaded into the container at startup. Refer to [the Unleash Proxy documentation](../reference/unleash-proxy) 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.js project** and **install the Unleash Client**: - - ```shell npm2yarn - 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_CLIENT_KEYS=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 - ``` - -#### When running the proxy with Node.js {#step-3-b-node} - -The Unleash Proxy accepts a `customStrategies` property as part of its initialization options. Use this to pass it initialized strategies. - -1. **Install the `unleash-client` package**. You'll need this to implement the custom strategy: - - ```shell npm2yarn - npm install unleash-client - ``` - -2. **Implement your strategy**. You can import it from a different file or put it in the same file as the Proxy initialization. For instance, a `TimeStampStrategy` could look 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(); - } - } - ``` - -3. **Pass the strategy to the Proxy Client** using the **`customStrategies`** option. A full code example: - - ```javascript - const { createApp } = require('@unleash/proxy'); - const { Strategy } = require('unleash-client'); - - class TimeStampStrategy extends Strategy { - constructor() { - super('TimeStamp'); - } - - isEnabled(parameters, context) { - return Date.parse(parameters.enableAfter) < Date.now(); - } - } - - const port = 3000; - - const app = createApp({ - unleashUrl: 'https://app.unleash-hosted.com/demo/api/', - unleashApiToken: - '*:default.56907a2fa53c1d16101d509a10b78e36190b0f918d9f122d', - clientKeys: ['proxy-secret', 'another-proxy-secret', 's1'], - refreshInterval: 1000, - // highlight-next-line - customStrategies: [new TimeStampStrategy()], - }); - - app.listen(port, () => - // eslint-disable-next-line no-console - console.log(`Unleash Proxy listening on http://localhost:${port}/proxy`), - ); - ``` diff --git a/website/docs/reference/actions.md b/website/docs/reference/actions.md index 7b517c0e1136..64a42ebf0631 100644 --- a/website/docs/reference/actions.md +++ b/website/docs/reference/actions.md @@ -38,7 +38,7 @@ Then you need to select a source. If you haven't created a signal endpoint yet, If the source you selected already received at least one signal, you'll be able to see a preview of the latest signal received. This can help you define the different filters that need to match for the action to be executed. -Filters work similarly to [feature flag strategy constraints](./strategy-constraints), where the signal payload acts as the context for the constraint evaluation. +Filters work similarly to [feature flag strategy constraints](./activation-strategies#constraints), where the signal payload acts as the context for the constraint evaluation. Filters are completely optional, so if you don't configure any filter your action will always be executed whenever you receive a new signal on the selected source. diff --git a/website/docs/reference/activation-strategies.md b/website/docs/reference/activation-strategies.md index fa80bc5d92ea..e7d866c885a6 100644 --- a/website/docs/reference/activation-strategies.md +++ b/website/docs/reference/activation-strategies.md @@ -2,130 +2,169 @@ title: Activation Strategies --- -It is powerful to be able to turn a feature on and off instantaneously, without redeploying the application. Activation strategies let you enable a feature only for a specified audience. Different strategies use different parameters. Predefined strategies are bundled with Unleash. The recommended strategy is the gradual rollout strategy with 100% rollout, which basically means that the feature should be enabled to everyone. +import VideoContent from '@site/src/components/VideoContent.jsx' -Unleash comes with a number of built-in strategies (described below) that can be enhanced with [constraints](https://docs.getunleash.io/reference/strategy-constraints) for fine-grained control. For more advanced use cases, where constraints do not fulfill your needs, you can add your own [custom activation strategies](../reference/custom-activation-strategies). However, while activation strategies are _defined_ on the server, the server does not _implement_ the strategies. Instead, activation strategy implementation is done client-side. This means that it is _the client_ that decides whether a feature should be enabled or not. +## Overview -All [server-side client SDKs](../reference/sdks#server-side-sdks) and the [Unleash Proxy](../reference/unleash-proxy) implement the default strategies (and allow you to add your own [custom strategy implementations](../reference/custom-activation-strategies#implementation)). The [front-end client SDKs](../reference/sdks#front-end-sdks) do not do the evaluation themselves, instead relying on the [Unleash Proxy](../reference/unleash-proxy) to take care of the implementation and evaluation. +An activation strategy determines who should get a feature. They allow you to enable and disable features for certain users without having to redeploy your application. For example, you can release features only to users with a specific user ID, email, IP address, and more. You can implement gradual rollouts to specific user segments, for example, those on a specific subscription plan or region. You can also use them to schedule feature releases or make features available for a limited time. -Some activation strategies require the client to provide the current [Unleash context](unleash-context) to the flag evaluation function for the evaluation to be done correctly. +An activation strategy is assigned to one [feature flag](/reference/feature-toggles) in one [environment](/reference/environments). A feature flag is enabled in a given context (for example, user or application) if at least one of its activation strategies resolves to true. -The following activation strategies are bundled with Unleash and always available: +The default activation strategy is a 100% gradual rollout, enabling the flag for all users. You can refine this using [rollout percentage](#rollout-percentage), [targeting](#targeting), and [variants](/reference/strategy-variants). -- [Standard](#standard) -- [UserIDs](#userids) -- [Gradual Rollout](#gradual-rollout) -- [IPs](#ips) -- [Hostnames](#hostnames) +Feature flags can have multiple activation strategies. Unleash evaluates each strategy independently, enabling the flag if any resolves to true. This behavior is equivalent to the OR logical operator. -## Standard {#standard} +For example, to roll out a feature to 75% of users while granting access to internal users, you can add two activation strategies as follows: +1. Gradual rollout to 100% with a constraint on the email address. +2. Gradual rollout to 75% (of all users). + +![A feature flag with two strategies](/img/activation-strategies-example.png) -A basic strategy that means "active for everyone". +## Rollout percentage -This strategy has the following modelling name in the code: +The rollout percentage determines the proportion of users exposed to a feature. It uses a normalized [MurmurHash](https://en.wikipedia.org/wiki/MurmurHash) of a user’s unique ID, ensuring consistent and random feature distribution. [Stickiness](/reference/stickiness) maintains a stable user experience across sessions. -- **default** +## Targeting -## UserIDs {#userids} +Segmentation and constraints allow you to define conditions for your activation strategies so that they will only be evaluated for users and applications that match those criteria. Constraints are individual conditional statements, while [segments](/reference/segments) are a reusable set of constraints that you can apply to multiple strategies. -Active for users with a `userId` defined in the `userIds` list. A typical use case is to enable a feature for a few specific devs or key persons before enabling the feature for everyone else. This strategy allows you to specify a list of user IDs that you want to expose the new feature for. (A user id may, of course, be an email if that is more appropriate in your system.) +### Constraints -**Parameters** +:::note Availability -- userIds - _List of user IDs you want the feature flag to be enabled for_ +**Version**: `4.16+` -This strategy has the following modelling name in the code: +::: -- **userWithId** +Constraints are conditional rules that determine whether a strategy applies, based on fields from the [Unleash context](/reference/unleash-context). Constraints can reference both [standard context fields](../reference/unleash-context#overview) and [custom context fields](../reference/unleash-context#custom-context-fields). -## Gradual Rollout {#gradual-rollout} +An activation strategy can have as many constraints as needed. When an activation strategy has multiple constraints, then every constraint must be evaluated to true for the strategy to be evaluated. This behavior is equivalent to the AND logical operator. -A flexible rollout strategy which combines all gradual rollout strategies in to a single strategy. This strategy allows you to customize what parameter should be sticky, and defaults to userId or sessionId. +You can use [Playground](/reference/playground) to experiment with different strategy and constraint configurations and how they would evaluate in a given context. -**Parameters** +For example, if you have two constraints: one where the user email must have the domain "@mycompany.com" and one where the user must have signed up for a beta program, then the strategy would only be evaluated for users with "@mycompany.com" emails that have signed up for the beta program. -- **stickiness** is used to define how we guarantee consistency for a gradual rollout. The same userId and the same rollout percentage should give predictable results. Configuration that should be supported: - - **default** - Unleash chooses the first value present on the context in defined order userId, sessionId, random. - - **userId** - guaranteed to be sticky on userId. If userId not present the behavior would be false - - **sessionId** - guaranteed to be sticky on sessionId. If sessionId not present the behavior would be false. - - **random** - no stickiness guaranteed. For every isEnabled call it will yield a random true/false based on the selected rollout percentage. -- **groupId** is used to ensure that different flags will **hash differently** for the same user. The groupId defaults to _feature flag name_, but the user can override it to _correlate rollout_ of multiple feature flags. -- **rollout** The percentage (0-100) you want to enable the feature flag for. + -This strategy has the following modelling name in the code: +#### Constraint structure -- **flexibleRollout** +A constraint has three parts: +- A **context field**: The [context field](/reference/unleash-context) to use for evaluation. +- An **operator**: One of the [constraint operators](#strategy-constraint-operators). +- **Values**: A value or list of values to use in the evaluation of the constraint. -### Custom stickiness {#custom-stickiness} +These parts turn the constraint into an expression that evaluates to true or false. Here are a few example constraints: -:::note SDK compatibility +| Context field | Operator | Values | Description | +|-----------------|-----------------|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| `userId` | `STR_ENDS_WITH` | `@example.com, @mycompany.com` | Evaluates to `true` for users whose user IDs end with `@example.com` or `@mycompany.com`. | +| `currentTime` | `DATE_AFTER` | `2022-06-05 21:43:22Z` | Evaluates to `true` if the current time is after `2022-06-05 21:43:22Z`. | +| `plan` | `IN` | `Premium`, `Plus` | Evaluates to `true` if the [custom context field](../reference/unleash-context#custom-context-fields) `plan` is either 'Premium' or 'Plus'. | -Custom stickiness is supported by all of our SDKs except for the Rust SDK. You can always refer to the [SDK compatibility table](../reference/sdks#server-side-sdk-compatibility-table) for the full overview. +#### Constraint operators -::: +Constraint operators help you define the conditional statements that get evaluated as part of the constraint. [Basic operators](#basic-operators) are available in all versions and SDKs. All other operators require Unleash version 4.9+ and [SDK compatibility](/reference/sdks#strategy-constraints). + +All constraints can be negated. For example: + +| Operator | Value | Context field | Result | +|-----------|--------------------------------------------------------------------|--|--------| +| `STR_ENDS_WITH` | "@user.com" | "hello@user.com" | true | +| NOT `STR_ENDS_WITH` | "@user.com" | "hello@user.com" | false | -By enabling the stickiness option on a custom context field you can use the custom context field to group users with the gradual rollout strategy. This will guarantee a consistent behavior for specific values of this context field. +##### Basic operators -## IPs {#ips} +| Operator | Description +|-----------|--------------------------------------------------------------------------------| +| `IN` | The context field is equal to any of the provided values; case sensitive. | +| `NOT_IN` | The context field is not equal to any of the values provided; case sensitive. | -The remote address strategy activates a feature flag for remote addresses defined in the IP list. We occasionally use this strategy to enable a feature only for IPs in our office network. +#### Numeric operators -**Parameters** +Numeric operators compare the numeric value of context fields with the provided value. Numeric operators only accept single values. -- IPs - _List of IPs to enable the feature for._ +| Operator | The context field is | +|-----------|--------------------------------------------------------------------------------| +| `NUM_EQ` | The context field is equal to the provided value. | +| `NUM_GT` | The context field is strictly greater than the provided value. | +| `NUM_GTE` | The context field is greater than or equal to the provided value. | +| `NUM_LT` | The context field is strictly less than the provided value. | +| `NUM_LTE` | The context field is less than or equal to the provided value. | -This strategy has the following modelling name in the code: -- **remoteAddress** +##### Date and time operators -## Hostnames {#hostnames} +All date and time operators require the `currentTime` context field, and the `currentTime` context field can only be used with date and time operators. With these operators, you can enable a feature before or after a specified time or make it available for a specific time span by combining the two operators. -The application hostname strategy activates a feature flag for client instances with a hostName in the `hostNames` list. +Date and time operators only support single values. -**Parameters** +| Operator | Description | +|---------------|--------------------------------| +| `DATE_AFTER` | `currentTime` is a date after the provided value. | +| `DATE_BEFORE` | `currentTime` is a date before the provided date. | -- hostNames - _List of hostnames to enable the feature flag for._ +##### String operators -This strategy has the following modelling name in the code: +String operators accept multiple values and can be set to be case-sensitive or case-insensitive. -- **applicationHostname** +| Operator | Description | +|-------------------|------------------------------------------------| +| `STR_CONTAINS` | The context field contains any of the provided string values. | +| `STR_ENDS_WITH` | The context field ends with any of the provided string values. | +| `STR_STARTS_WITH` | The context field starts with any of the provided string values. | -## Multiple activation strategies {#multiple-activation-strategies} -You can apply as many activation strategies to a flag as you want. When a flag has multiple strategies, Unleash will check each strategy in isolation. If any one of the strategies would enable the flag for the current user, then the flag is enabled. +##### Versioning (SemVer) operators -As an example, consider a case where you want to roll a feature out to 75% of your users. However, you also want to make sure that you and your product lead get access to the feature. To achieve this, you would apply a **gradual rollout** strategy and set it to 75%. Additionally, you would add a **user IDs** strategy and add `engineer@mycompany.com` and `productlead@mycompany.com`. +SemVer operators are used to compare version numbers such as application versions or dependency versions. SemVer operators only support single values. -![A feature flag with two active strategies: a user ID strategy and a gradual rollout strategy. The strategies are configured as described in the preceding paragraph.](/img/control_rollout_multiple_strategies.png) +The value must start with and contain at least major, minor, and patch versions. For example, `1.2.3`. Optionally, you can also define pre-release version information by adding a hyphen and series of full-stop separated identifiers after the patch version. For example, `1.2.3-rc.2`. Values with pre-release versions are considered less than versions without a pre-release in accordance with [the SemVer specification, item 11](https://semver.org/#spec-item-11). -## Deprecated strategies +| Operator | Description | +|-------------|----------------------------------------------| +| `SEMVER_EQ` | The context field is equal to the provided value. | +| `SEMVER_GT` | The context field is strictly greater than the provided value. | +| `SEMVER_LT` | The context field is strictly less than the provided value. | -### gradualRolloutUserId (DEPRECATED from v4) - Use Gradual rollout instead {#gradualrolloutuserid-deprecated-from-v4---use-gradual-rollout-instead} +#### Best practices -The `gradualRolloutUserId` strategy gradually activates a feature flag for logged-in users. Stickiness is based on the user ID. The strategy guarantees that the same user gets the same experience every time across devices. It also assures that a user which is among the first 10% will also be among the first 20% of the users. That way, we ensure the users get the same experience, even if we gradually increase the number of users exposed to a particular feature. To achieve this, we hash the user ID and normalize the hash value to a number between 1 and 100 with a simple modulo operator. +Server-side SDKs fetch the full feature flag configuration associated with your API key from Unleash. You can use API keys scoped to specific projects or environments to optimize payload size. -![hash_and_normalise](/img/hash_and_normalise.png) +However, every value that you add to your feature flag constraints, increases the payload size. We recommend avoiding large constraint value lists. For example, instead of adding many user IDs or emails to the constraint value list, consider what properties those users share. This typically helps define and use a [custom context field](/reference/unleash-context#custom-context-field) instead. -Starting from v3.x all clients should use the 32-bit [MurmurHash3](https://en.wikipedia.org/wiki/MurmurHash) algorithm to normalize values. ([issue 247](https://github.com/Unleash/unleash/issues/247)) -**Parameters** +## Add an activation strategy with a constraint -- percentage - _The percentage (0-100) you want to enable the feature flag for._ -- groupId - _Used to define an activation group, which allows you to correlate rollout across feature flags._ +To add an activation strategy with a constraint to a feature flag, do the following: -### gradualRolloutSessionId (DEPRECATED from v4) - Use Gradual rollout instead {#gradualrolloutsessionid-deprecated-from-v4---use-gradual-rollout-instead} +1. Open the Admin UI and go to the feature flag you'd like to add a strategy to. +2. Select the environment you want to configure and click **Add strategy**. +3. In the **Targeting** tab, go to the **Constraints** section, and click **Add constraint**. +4. Select a context field to constrain on, for example, `email`. +5. Set your desired operator, for example, `STR_ENDS_WITH`. +6. Enter a value that the operator should evaluate, such as `@user.com`, and click **Add values**. Then click **Done**. +7. Click **Save strategy**. -Similar to `gradualRolloutUserId` strategy, this strategy gradually activates a feature flag, with the exception being that the stickiness is based on the session IDs. This makes it possible to target all users (not just logged-in users), guaranteeing that a user will get the same experience within a session. +## Client-side implementation -**Parameters** +Activation strategies are defined on the server but implemented client-side. The client determines whether a feature should be enabled based on the activation strategies. -- percentage - _The percentage (0-100) you want to enable the feature flag for._ -- groupId - _Used to define an activation group, which allows you to correlate rollout across feature flags._ +All [server-side client SDKs](../reference/sdks#server-side-sdks) and [Unleash Edge](../reference/unleash-edge) implement the default activation strategy. The [front-end client SDKs](../reference/sdks#front-end-sdks) do not perform evaluations themselves. Instead, they rely on [Unleash Edge](../reference/unleash-edge) to handle the implementation and evaluation. -### gradualRolloutRandom (DEPRECATED from v4) - Use Gradual rollout instead {#gradualrolloutrandom-deprecated-from-v4---use-gradual-rollout-instead} +When using strategies with constraints, the client must provide the current [Unleash context](unleash-context) to the flag evaluation function for the evaluation to be done correctly. All official Unleash client SDKs support the option to pass dynamic context values to the `isEnabled()` function (or the SDK's equivalent). -The `gradualRolloutRandom` strategy randomly activates a feature flag and has no stickiness. We have found this rollout strategy very useful in some scenarios, especially when we enable a feature which is not visible to the user. It is also the strategy we use to sample metrics and error reports. +If the constraint uses a standard Unleash context field, set the context field to the required value. If the constraint uses a custom context field, use the Unleash context's `properties` field. Use the name of the custom context field as a key and set the value to your desired string. + +Unleash SDKs expect all context values to be strings. If you use an operator that acts on non-string values, such as [numeric operators](#numeric-operators) or [date and time operators](#date-and-time-operators), the SDKs attempt to convert the string into the expected type. If the conversion fails, the constraint evaluates to `false`. + +## Predefined strategy types + +:::caution +[Predefined strategy types](/reference/predefined-strategy-types), such as UserIDs, IPs, and Hosts are a legacy implementation. Please use the default strategy with constraints to achieve your desired targeting. +::: -**Parameters** +## Custom activation strategies -- percentage - _The percentage (0-100) you want to enable the feature flag for._ +:::caution +[Custom activation strategies](/reference/custom-activation-strategies) are deprecated. Please use the default strategy with constraints. +::: \ No newline at end of file diff --git a/website/docs/reference/api-tokens-and-client-keys.mdx b/website/docs/reference/api-tokens-and-client-keys.mdx index 1e59a54e6386..bc0e97c10d55 100644 --- a/website/docs/reference/api-tokens-and-client-keys.mdx +++ b/website/docs/reference/api-tokens-and-client-keys.mdx @@ -1,5 +1,6 @@ --- title: API Tokens and Client Keys +pagination_next: reference/front-end-api --- For Unleash to be of any use, it requires at least a server and a [consuming client](../reference/sdks). More advanced use cases may call for multiple clients, automated feature flag updates, the [Unleash proxy](../reference/unleash-proxy) and [Unleash proxy clients](../reference/sdks#front-end-sdks), and more. To facilitate communication between all these moving parts, Unleash uses a system of API tokens and client keys, all with a specific purpose in mind. diff --git a/website/docs/reference/api/legacy/unleash/admin/segments.mdx b/website/docs/reference/api/legacy/unleash/admin/segments.mdx index 81d0503a8f93..894de27747cc 100644 --- a/website/docs/reference/api/legacy/unleash/admin/segments.mdx +++ b/website/docs/reference/api/legacy/unleash/admin/segments.mdx @@ -330,18 +330,18 @@ This section describes the data objects returned by the endpoints in the segment :::note `values` and `value` -Some constraint operators only support single values. If a constraint uses one of these operators, the payload will contain a `value` property with the correct value. However, for backwards compatibility reasons, the payload will *also* contain a `values` property. If the operator accepts multiple values, the `value` property will not be present. Visit the [strategy constraints documentation](/reference/strategy-constraints) for more information on what operators support what number of values. +Some constraint operators only support single values. If a constraint uses one of these operators, the payload will contain a `value` property with the correct value. However, for backwards compatibility reasons, the payload will *also* contain a `values` property. If the operator accepts multiple values, the `value` property will not be present. Visit the [strategy constraints documentation](/reference/activation-strategies#constraints) for more information on what operators support what number of values. ::: | Property | Type | Required | Description | Example value | |-------------------|-----------------------------------------------------------------------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------| | `contextName` | string | Yes | The name of the context field targeted by the constraint. | `"myContextField"` | -| `operator` | string, the name of one of the [constraint operators](/reference/strategy-constraints) | Yes | The operator to apply to the context field. | `"DATE_BEFORE"` | +| `operator` | string, the name of one of the [constraint operators](/reference/activation-strategies#constraints) | Yes | The operator to apply to the context field. | `"DATE_BEFORE"` | | `values` | a list of strings | Yes | The list of values to apply the constraint operator to. | `["value a", "value b"]` | | `value` | string | No | The value to apply the constraint operator to. | `"15"` | -| `inverted` | boolean | No | Whether the result of [the constraint will be negated or not](/reference/strategy-constraints#constraint-negation). | `false` | -| `caseInsensitive` | boolean string | No | Whether the constraint operator is case sensitive or not. Only [applies to some string-based operators](/reference/strategy-constraints#string-operators). | `false` | +| `inverted` | boolean | No | Whether the result of [the constraint will be negated or not](/reference/activation-strategies#constraint-operators). | `false` | +| `caseInsensitive` | boolean string | No | Whether the constraint operator is case sensitive or not. Only [applies to some string-based operators](/reference/activation-strategies#string-operators). | `false` | ### Activation strategy {#activation-strategy-type-description} diff --git a/website/docs/reference/api/legacy/unleash/client/features.md b/website/docs/reference/api/legacy/unleash/client/features.md index 8435b1d2f3b8..1cd17977ae06 100644 --- a/website/docs/reference/api/legacy/unleash/client/features.md +++ b/website/docs/reference/api/legacy/unleash/client/features.md @@ -120,7 +120,7 @@ Used to fetch details about a specific feature flag. This is mainly provided to ::: -Strategy definitions may also contain a `constraints` property. Strategy constraints is a feature in Unleash which work on context fields, which is defined as part of the [Unleash Context](/reference/unleash-context.md). The purpose is to define a set of rules where all needs to be satisfied in order for the activation strategy to evaluate to true. A [high level description](https://www.unleash-hosted.com/articles/strategy-constraints) of it is available online. +Strategy definitions may also contain a `constraints` property. Strategy constraints is a feature in Unleash which work on context fields, which is defined as part of the [Unleash Context](/reference/unleash-context.md). The purpose is to define a set of rules where all needs to be satisfied in order for the activation strategy to evaluate to true. **Example response:** diff --git a/website/docs/reference/applications.mdx b/website/docs/reference/applications.mdx index 666cc43c75f3..97dea949c8b4 100644 --- a/website/docs/reference/applications.mdx +++ b/website/docs/reference/applications.mdx @@ -1,5 +1,6 @@ --- title: Applications +pagination_next: reference/service-accounts --- import Figure from '@site/src/components/Figure/Figure.tsx' diff --git a/website/docs/reference/change-requests.mdx b/website/docs/reference/change-requests.mdx index 747100e5239b..026ccdacc35d 100644 --- a/website/docs/reference/change-requests.mdx +++ b/website/docs/reference/change-requests.mdx @@ -111,7 +111,7 @@ Unleash currently offers two distinct ways to schedule changes. Each method has The first method is through scheduled change requests, as we have explained in the preceding sections. Scheduled change requests make it easy to see all the changes across multiple flags and strategies in one view and makes it easy to reschedule or reject them. However, because scheduled changes rely on flags and strategy configurations, conflicts can arise causing the schedule to fail. -The second method uses Unleash's [constraints](strategy-constraints) and the [DATE_AFTER operator](strategy-constraints#date-and-time-operators) to encode when changes should take effect. The pros of this method is that because these changes can be applied immediately, you won't run into any conflicts when they happen. The cons are that you'll need to apply the same constraints to all the parts that you want to change and that there is no easy way to see all the changes in one view. You also can not scheduled changes to a segment in this way. When using this option, we recommend that you use [segments](segments) if you want to schedule multiple changes, so that their application time stays in sync. +The second method uses Unleash's [constraints](activation-strategies#constraints) and the [DATE_AFTER operator](activation-strategies#date-and-time-operators) to encode when changes should take effect. The pros of this method is that because these changes can be applied immediately, you won't run into any conflicts when they happen. The cons are that you'll need to apply the same constraints to all the parts that you want to change and that there is no easy way to see all the changes in one view. You also can not scheduled changes to a segment in this way. When using this option, we recommend that you use [segments](segments) if you want to schedule multiple changes, so that their application time stays in sync. Another important distinction is how these changes affect your connected SDKs. If you use constraints (or segments), then any connected SDK will be aware of the schedule ahead of time. That means that even if the SDK can not connect to Unleash at the scheduled time, it will still activate the changes because it's encoded in its constraints. On the other hand, if you use change requests to schedule changes, SDKs **must** update their configuration after the scheduled time to be aware of the changes. diff --git a/website/docs/reference/custom-activation-strategies.md b/website/docs/reference/custom-activation-strategies.md index e2e8da7f85d5..e32ef5ef6a04 100644 --- a/website/docs/reference/custom-activation-strategies.md +++ b/website/docs/reference/custom-activation-strategies.md @@ -2,12 +2,8 @@ title: Custom Activation 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 should be considered an advanced feature. In most cases [strategy constraints](https://docs.getunleash.io/reference/strategy-constraints) provides enough control without the additional complexity. - +:::caution +[Custom activation strategies](/reference/custom-activation-strategies) are deprecated. Please use the [default activation strategy](/reference/activation-strategies) with constraints. ::: **Custom activation strategies** let you define your own activation strategies to use with Unleash. When the [built-in activation strategies](../reference/activation-strategies.md) aren't enough, custom activation strategies are there to provide you with the flexibility you need. @@ -22,7 +18,7 @@ You define custom activation strategies on your Unleash instance, either via the - A strategy **name**: You'll use this to refer to the strategy in the UI and in code. The strategy name should make it easy to understand what the strategy does. For instance, if a strategy uses contact numbers to determine whether a feature should be enabled, then _ContactNumbers_ would be a good name. - An optional **description**: Use this to describe what the strategy should do. -- An optional list of **parameters**: The parameter list lets you pass arguments to your custom activation strategy. These will be made available to your custom strategy implementation. How you interact with them differs between SDKs, but refer to the [Node.js example in the how-to guide](../how-to/how-to-use-custom-strategies.md) for a rough idea. +- An optional list of **parameters**: The parameter list lets you pass arguments to your custom activation strategy. These will be made available to your custom strategy implementation. 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. @@ -62,7 +58,7 @@ If you have not implemented the strategy in your client SDK, the check will alwa ::: -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). +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. 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](/docs/generated/sdks/client-side/android-proxy.md), [JavaScript](/docs/generated/sdks/client-side/javascript-browser.md), [React](/docs/generated/sdks/client-side/react.md), [iOS](/docs/generated/sdks/client-side/ios-proxy.md), [Flutter](/docs/generated/sdks/client-side/flutter.md)), the custom activation strategy must be implemented in the [Unleash Proxy](../generated/unleash-proxy.md). diff --git a/website/docs/reference/feature-toggles.mdx b/website/docs/reference/feature-toggles.mdx index 519ee79c5c32..bfc3d9d62409 100644 --- a/website/docs/reference/feature-toggles.mdx +++ b/website/docs/reference/feature-toggles.mdx @@ -1,5 +1,6 @@ --- title: Feature Flags +pagination_next: reference/activation-strategies --- ## Overview @@ -198,3 +199,21 @@ You can delete archived flags by navigating to the [feature flag archive](#view- However, we recommend not deleting feature flags unless they are completely removed from your codebase. If you delete a flag and later create a new one with the same name, it might unintentionally reactivate old code that still references the original flag. +## Tags + +:::note Availability + +**Version**: `3.11+` + +::: + + +Tags can be used to group feature flags by any criteria, such as functionality, teams, or products, to make them easier to filter and manage. Tags are organized by type, which you can define in the Admin UI under **Configure > Tag types**. + +To assign tags to a feature flag, do the following: +1. Open the feature flag and go to the **Tags for this feature flag** section. +2. Click **Add new tag**. +3. Select a tag type, and enter a new value for the tag or select an existing one. You can add multiple tags at once. +4. Click **Save tags**. + +For example, you can create a `slack` tag type and assign Slack channel names as tag values. This lets you configure a Slack integration to send updates about specific feature flags to the correct channels. diff --git a/website/docs/reference/front-end-api.md b/website/docs/reference/front-end-api.md index 41f3cc065b42..638384f83d0b 100644 --- a/website/docs/reference/front-end-api.md +++ b/website/docs/reference/front-end-api.md @@ -1,5 +1,5 @@ --- -title: Front-end API access +title: Front-end API Access --- :::note Availability diff --git a/website/docs/reference/impression-data.md b/website/docs/reference/impression-data.md index 0236247fde55..db727d06463f 100644 --- a/website/docs/reference/impression-data.md +++ b/website/docs/reference/impression-data.md @@ -1,5 +1,6 @@ --- title: Impression Data +pagination_next: reference/events --- :::note Availability diff --git a/website/docs/reference/notifications.md b/website/docs/reference/notifications.md index e0a1153a6a82..20f0ce50b7b2 100644 --- a/website/docs/reference/notifications.md +++ b/website/docs/reference/notifications.md @@ -1,5 +1,6 @@ --- title: Notifications +pagination_next: reference/login-history --- :::note Availability diff --git a/website/docs/reference/playground.mdx b/website/docs/reference/playground.mdx index 38ed53316a21..db5f15550815 100644 --- a/website/docs/reference/playground.mdx +++ b/website/docs/reference/playground.mdx @@ -108,11 +108,15 @@ There's currently two cases where the playground can't evaluate the strategy: 1. The [strategy is a custom strategy](#custom-strategies) and the playground doesn't have an implementation for the strategy. 2. The [strategy is the 'Application Hostname' strategy](#application-hostname). -Even if the playground doesn't recognize or otherwise can't evaluate a specific strategy, it _may_ still evaluate the overall strategy result to `false` (and be certain that it is the right result). If a strategy has [constraints](../reference/strategy-constraints) or [segments](segments) that are not satisfied, the playground knows that the strategy result wouldn't be `true`, regardless of the actual strategy implementation. As such, if a strategy can't be evaluated, it can be **either** _unknown_ or _`false`_. +Even if the playground doesn't recognize or otherwise can't evaluate a specific strategy, it _may_ still evaluate the overall strategy result to `false` (and be certain that it is the right result). If a strategy has [constraints](../reference/activation-strategies#constraints) or [segments](segments) that are not satisfied, the playground knows that the strategy result wouldn't be `true`, regardless of the actual strategy implementation. As such, if a strategy can't be evaluated, it can be **either** _unknown_ or _`false`_. ### Custom Strategies -The playground does not have any implementations for [custom strategies](../reference/custom-activation-strategies) and adding custom strategy implementations to Unleash is not currently supported. Because of this, custom strategies will never be evaluated as `true`. +:::caution +[Custom activation strategies](/reference/custom-activation-strategies) are deprecated. Please use the [default activation strategy](/reference/activation-strategies) with constraints. +::: + +The playground does not have any implementations for [custom strategies](../reference/custom-activation-strategies). As a result, custom strategies do not evaluate to `true` regarless of the context. ### The Application Hostname strategy {#application-hostname} diff --git a/website/docs/reference/predefined-strategy-types.mdx b/website/docs/reference/predefined-strategy-types.mdx new file mode 100644 index 000000000000..57ea3ee3e81d --- /dev/null +++ b/website/docs/reference/predefined-strategy-types.mdx @@ -0,0 +1,69 @@ +--- +title: Predefined strategy types +--- + +:::caution +Predefined strategy types are a legacy implementation. Please use the [default strategy](/reference/activation-strategies) with strategy constraints to achieve your desired targeting. +::: + +## UserIDs + +The `userWithId` strategy is active for users with a `userId` defined in the `userIds` list. + +**Parameters:** +- userIds - _List of user IDs you want the feature flag to be enabled for_ + +## Flexible Gradual Rollout + +The `flexibleRollout` stategy has the following parameters: +- stickiness - Used to define how we guarantee consistency for a gradual rollout. The same userId and the same rollout percentage should give predictable results. Configuration that should be supported: + - default - Unleash chooses the first value present on the context in defined order userId, sessionId, random. + - userId - Guaranteed to be sticky on userId. If userId not present the behavior would be false + - sessionId - Guaranteed to be sticky on sessionId. If sessionId not present the behavior would be false. + - random - No stickiness guaranteed. For every isEnabled call it will yield a random true/false based on the selected rollout percentage. +- groupId - Used to ensure that different flags will **hash differently** for the same user. The groupId defaults to _feature flag name_, but the user can override it to _correlate rollout_ of multiple feature flags. +- rollout - The percentage (0-100) you want to enable the feature flag for. + +## IPs + +The `remoteAddress` strategy activates a feature flag for remote addresses defined in the IP list. + +**Parameters:** +- IPs - List of IPs to enable the feature for. + + +## Hosts + +The `applicationHostname` strategy activates a feature flag for client instances with a hostName in the `hostNames` list. + +**Parameters** + +- hostNames - List of hostnames to enable the feature flag for. + + +### Gradual rollout with user ID + +The `gradualRolloutUserId` strategy gradually activates a feature flag for logged-in users. Stickiness is based on the user ID. The strategy guarantees that the same user gets the same experience every time across devices. It also assures that a user which is among the first 10% will also be among the first 20% of the users. That way, we ensure the users get the same experience, even if we gradually increase the number of users exposed to a particular feature. To achieve this, we hash the user ID and normalize the hash value to a number between 1 and 100 with a simple modulo operator. + +![hash_and_normalise](/img/hash_and_normalise.png) + +Starting from v3.x all clients should use the 32-bit [MurmurHash3](https://en.wikipedia.org/wiki/MurmurHash) algorithm to normalize values. ([issue 247](https://github.com/Unleash/unleash/issues/247)) + +**Parameters:** +- percentage - The percentage (0-100) you want to enable the feature flag for. +- groupId - Used to define an activation group, which allows you to correlate rollout across feature flags. + +### Gradual rollout with session ID + +Similar to `gradualRolloutUserId` strategy, this strategy gradually activates a feature flag, with the exception being that the stickiness is based on the session IDs. + +**Parameters:** +- percentage - The percentage (0-100) you want to enable the feature flag for. +- groupId - Used to define an activation group, which allows you to correlate rollout across feature flags. + +### Random gradual rollout + +The `gradualRolloutRandom` strategy randomly activates a feature flag and has no stickiness. We have found this rollout strategy very useful in some scenarios, especially when we enable a feature which is not visible to the user. It is also the strategy we use to sample metrics and error reports. + +**Parameters:** +- percentage - The percentage (0-100) you want to enable the feature flag for. diff --git a/website/docs/reference/projects.mdx b/website/docs/reference/projects.mdx index 10fe92474fbb..e58b3d6dfb63 100644 --- a/website/docs/reference/projects.mdx +++ b/website/docs/reference/projects.mdx @@ -1,6 +1,7 @@ --- id: projects title: Projects +pagination_next: reference/project-collaboration-mode --- ## Overview @@ -102,7 +103,7 @@ import Figure from '@site/src/components/Figure/Figure.tsx' Each project has a default strategy of [gradual rollout](./activation-strategies#gradual-rollout) to 100% of the user base. The default strategy only applies when **no active strategies** are defined for a flag in a specific environment. -You can change the default strategies of a project per environment. You can customize the default strategies by changing the rollout percentage and [stickiness](./stickiness) and adding [segments](./segments), [constraints](./strategy-constraints), and [variants](./strategy-variants). +You can change the default strategies of a project per environment. You can customize the default strategies by changing the rollout percentage and [stickiness](./stickiness) and adding [segments](./segments), [constraints](./activation-strategies#-constraints), and [variants](./strategy-variants). To change the default strategy for an environment in a project: diff --git a/website/docs/reference/rbac.md b/website/docs/reference/rbac.md index 3e27001683d6..984a68418caf 100644 --- a/website/docs/reference/rbac.md +++ b/website/docs/reference/rbac.md @@ -1,6 +1,6 @@ --- id: rbac -title: Role-based Access control +title: Role-based Access Control --- :::note Availability diff --git a/website/docs/reference/resource-limits.mdx b/website/docs/reference/resource-limits.mdx index 0d5338935c64..8aaffbc99edc 100644 --- a/website/docs/reference/resource-limits.mdx +++ b/website/docs/reference/resource-limits.mdx @@ -15,22 +15,26 @@ To ensure that Unleash operates smoothly, it includes resource limits for some o The resources and their respective limits and environment variables are: -| Resource | [Open Source](https://www.getunleash.io/pricing) limit | [Pro](/availability#plans) limit | [Enterprise](https://www.getunleash.io/pricing) limit | Environment variable | -|----------------------------------------------------------------|----------:|----------:|-----------------:|------------------------------------------------| -| [Feature flags](./feature-toggles)[^1] | 5,000 | 5,000 | 50,000 | `UNLEASH_FEATURE_FLAGS_LIMIT` | -| [Strategies](./activation-strategies) per flag per environment | 30 | 30 | 30 | `UNLEASH_FEATURE_ENVIRONMENT_STRATEGIES_LIMIT` | -| [Constraints](./strategy-constraints) per strategy | 30 | 30 | 30 | `UNLEASH_CONSTRAINTS_LIMIT` | -| Values per [constraint](./strategy-constraints) | 250 | 250 | 1,000 | `UNLEASH_CONSTRAINT_VALUES_LIMIT` | -| [Segments](./segments) | 300 | 300 | 300 | `UNLEASH_SEGMENTS_LIMIT` | -| [API tokens](./api-tokens-and-client-keys) | 2,000 | 2,000 | 2,000 | `UNLEASH_API_TOKENS_LIMIT` | -| [Projects](./projects) | 1 | 3 | 500 | `UNLEASH_PROJECTS_LIMIT` | -| [Environments](./environments) | 2 | 2 | 50 | `UNLEASH_ENVIRONMENTS_LIMIT` | -| [Signal](./signals) endpoints | N/A | N/A | 5 | `UNLEASH_SIGNAL_ENDPOINTS_LIMIT` | -| [Signal](./signals) tokens per endpoint | N/A | N/A | 5 | `UNLEASH_SIGNAL_TOKENS_PER_ENDPOINT_LIMIT` | -| [Action](./actions) set actions | N/A | N/A | 10 | `UNLEASH_ACTION_SET_ACTIONS_LIMIT` | -| [Action](./actions) sets per project | N/A | N/A | 5 | `UNLEASH_ACTION_SETS_PER_PROJECT_LIMIT` | -| [Action](./actions) set filters | N/A | N/A | 5 | `UNLEASH_ACTION_SET_FILTERS_LIMIT` | -| [Action](./actions) set filter values | N/A | N/A | 25 | `UNLEASH_ACTION_SET_FILTER_VALUES_LIMIT` | +| Resource | [Open Source](https://www.getunleash.io/pricing) limit | [Pro](/availability#plans) limit | [Enterprise](https://www.getunleash.io/pricing) limit | Environment variable | +|--------------------------------------------------------------------------------------|--------------------------------------------------------|----------------------------------|-------------------------------------------------------|------------------------------------------------| +| Active [feature flags](./feature-toggles) | 5,000 | 5,000 | 50,000 | `UNLEASH_FEATURE_FLAGS_LIMIT` | +| [Strategies](./activation-strategies) per flag per environment | 30 | 30 | 30 | `UNLEASH_FEATURE_ENVIRONMENT_STRATEGIES_LIMIT` | +| [Constraints](./activation-strategies#-constraints) per strategy | 30 | 30 | 30 | `UNLEASH_CONSTRAINTS_LIMIT` | +| Values per [constraint](./activation-strategies#-constraints) | 250 | 250 | 1,000 | `UNLEASH_CONSTRAINT_VALUES_LIMIT` | +| [Segments](./segments) | 300 | 300 | 300 | `UNLEASH_SEGMENTS_LIMIT` | +| [Segments](./segments) per [strategy](./activation-strategies) | 5 | 5 | 5 | `UNLEASH_STRATEGY_SEGMENTS_LIMIT` | +| [Constraint](./activation-strategies#-constraints) values in a [segment](./segments) | 1,000 | 1,000 | 1,000 | `UNLEASH_SEGMENT_VALUES_LIMIT` | +| [API tokens](./api-tokens-and-client-keys) | 2,000 | 2,000 | 2,000 | `UNLEASH_API_TOKENS_LIMIT` | +| [Projects](./projects) | 1 | 3 | 500 | `UNLEASH_PROJECTS_LIMIT` | +| [Environments](./environments) | 2 | 2 | 50 | `UNLEASH_ENVIRONMENTS_LIMIT` | +| [Signal](./signals) endpoints | N/A | N/A | 5 | `UNLEASH_SIGNAL_ENDPOINTS_LIMIT` | +| [Signal](./signals) tokens per endpoint | N/A | N/A | 5 | `UNLEASH_SIGNAL_TOKENS_PER_ENDPOINT_LIMIT` | +| [Action](./actions) set actions | N/A | N/A | 10 | `UNLEASH_ACTION_SET_ACTIONS_LIMIT` | +| [Action](./actions) sets per project | N/A | N/A | 5 | `UNLEASH_ACTION_SETS_PER_PROJECT_LIMIT` | +| [Action](./actions) set filters | N/A | N/A | 5 | `UNLEASH_ACTION_SET_FILTERS_LIMIT` | +| [Action](./actions) set filter values | N/A | N/A | 25 | `UNLEASH_ACTION_SET_FILTER_VALUES_LIMIT` | + + ## Overriding the limits @@ -51,6 +55,4 @@ If you try to set their limits lower than that, Unleash will automatically adjus If you operate a self-hosted Unleash instance, you can adjust the limit yourself. For hosted users of Unleash, you'll need to reach out and talk to your Unleash contact. -The only limits that can't be changed, are projects and environments for [Open Source](https://www.getunleash.io/pricing) and [Pro](/availability#plans) instances. - -[^1]: Archived feature flags do not count towards your feature flag total. The limit only applies to active (i.e. not archived) feature flags. +The only limits that can't be changed, are projects and environments for [Open Source](https://www.getunleash.io/pricing) and [Pro](/availability#plans) instances. \ No newline at end of file diff --git a/website/docs/reference/sdks/index.mdx b/website/docs/reference/sdks/index.mdx index b134bc205f95..cb37ad78bdc5 100644 --- a/website/docs/reference/sdks/index.mdx +++ b/website/docs/reference/sdks/index.mdx @@ -75,13 +75,13 @@ If you see an item marked with a ❌ that you would find useful, feel free to re | [Standard](./activation-strategies#standard) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [Gradual rollout](./activation-strategies#gradual-rollout) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [Gradual rollout: custom stickiness](./activation-strategies#customize-stickiness-beta) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | -| [UserID](./activation-strategies#userids) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [IP](./activation-strategies#ips) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [IP](./activation-strategies#ips): CIDR syntax | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ✅ | ✅ | -| [Hostname](./activation-strategies#hostnames) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [UserID](./predefined-strategy-types#userids) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [IP](./predefined-strategy-types#ips) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [IP](./predefined-strategy-types#ips): CIDR syntax | ✅ | ✅ | ✅ | ✅ | ✅ | ⭕ | ✅ | ✅ | +| [Hostname](./predefined-strategy-types#hostnames) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | **Category: [Custom strategies](./custom-activation-strategies)** | | | | | | | | | | Basic support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| **Category: [Strategy constraints](./strategy-constraints)** | | | | | | | | | +| **Category: [Strategy constraints](./activation-strategies#constraints)** | | | | | | | | | | Basic support (`IN`, `NOT_IN` operators) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | Advanced support (Semver, date, numeric, and extended string operators) (introduced in) | ✅ (5.1) | ✅ (3.12) | ✅ (3.3) | ✅ (5.1) | ✅ (4.2) | ✅ (2.1) | ✅ (1.3.1) | ⭕ | | **Category: [Unleash Context](./unleash-context)** | | | | | | | | | diff --git a/website/docs/reference/search-operators.md b/website/docs/reference/search-operators.md index 97d38cdc3343..c612d0799892 100644 --- a/website/docs/reference/search-operators.md +++ b/website/docs/reference/search-operators.md @@ -1,5 +1,5 @@ --- -title: Search with filters/operators +title: Search --- :::note Availability diff --git a/website/docs/reference/segments.mdx b/website/docs/reference/segments.mdx index f1a456ef1e97..3c58e6780976 100644 --- a/website/docs/reference/segments.mdx +++ b/website/docs/reference/segments.mdx @@ -14,7 +14,7 @@ import VideoContent from '@site/src/components/VideoContent.jsx' -A **segment** is a reusable collection of [strategy constraints](./strategy-constraints). Like with strategy constraints, you apply segments to [feature flag activation strategies](./activation-strategies). +A **segment** is a reusable collection of [strategy constraints](./activation-strategies#-constraints). Like with strategy constraints, you apply segments to [feature flag activation strategies](./activation-strategies). You can apply the same segment to multiple activation strategies. If you update the segment, the changes will affect every strategy that uses that segment. @@ -56,9 +56,7 @@ You **can** [configure segment limits](/using-unleash/deploy/configuring-unleash ### A note on large segments {#large-segments} -Segments are just constraints, so any limitations that apply to constraints also apply to segments. - -This means that if you want to add a hundred different user IDs to one of your constraints, you are most likely better off thinking about finding another way to solve this problem. That may be using a different abstraction or finding another pattern that you can use instead. Refer to the section on [constraint limitations](../reference/strategy-constraints#limitations) for a more thorough explanation or to [the topic guide on using Unleash with large constraints](../understanding-unleash/managing-constraints) for a more thorough . +Segments are just constraints, so any limitations that apply to constraints also apply to segments. See [Using Unleash with large constraints](../understanding-unleash/managing-constraints) for a more guidance. ## Creating, updating, and deleting segments diff --git a/website/docs/reference/stickiness.md b/website/docs/reference/stickiness.md index 2e436d26651c..6179d31a4630 100644 --- a/website/docs/reference/stickiness.md +++ b/website/docs/reference/stickiness.md @@ -16,7 +16,7 @@ Because the number assigned to a user won't change, Unleash also guarantees that For instance: When using the [gradual rollout activation strategy](../reference/activation-strategies#gradual-rollout), any user whose number is less than or equal to the rollout percentage will see the feature. This means that the same users will keep seeing the feature even as you increase the percentage of your user base that sees the feature. -## Custom stickiness {#custom-stickiness} +## Custom stickiness :::note Availability diff --git a/website/docs/reference/strategy-constraints.mdx b/website/docs/reference/strategy-constraints.mdx deleted file mode 100644 index 94d59f5f8043..000000000000 --- a/website/docs/reference/strategy-constraints.mdx +++ /dev/null @@ -1,220 +0,0 @@ ---- -title: Strategy Constraints ---- -import VideoContent from '@site/src/components/VideoContent.jsx' - -:::note Availability - -**Version**: `4.16+` - -::: - -:::caution undefined behavior - -When using _advanced strategy constraints_ (any operator that isn't `IN` or `NOT_IN`), *make sure your client SDK is up to date* and supports this feature. For older versions of the client SDKs we **cannot guarantee** any specific behavior. Please see the [incompatibilities section](#incompatibilities) for more information. - -::: - -**Strategy constraints** are conditions that must be satisfied for an [activation strategy](../reference/activation-strategies) to be evaluated for a feature flag. -With strategy constraints, you can: -- roll out a feature **only to users in a specific region** -- schedule a feature to be **released at a specific time** -- make a feature available for **a limited time only** -- release a feature to users with one of a set of **email addresses** -- ... and much more! - -Strategy constraints use fields from the [Unleash Context](../reference/unleash-context) to determine whether a strategy should apply or not. -You can constrain both on [standard context fields](../reference/unleash-context#structure) and on [custom context fields](../reference/unleash-context#custom-context-fields). - -:::info -Unleash SDKs expect all context values to be strings. If you use an operator that acts on non-string values, such as [numeric operators](#numeric-operators) or [date and time operators](#date-and-time-operators), the SDK will attempt to convert the string into the expected type. If the conversion fails, the constraint will evaluate to `false`. -::: - -This page explains what strategy constraints are in Unleash and how they work. If you want to know *how you add* strategy constraints to an activation strategy, see [the corresponding how-to guide](../how-to/how-to-add-strategy-constraints). - - - - -## Constraining on custom context fields - -:::info Making custom context fields available -To be able to constrain on a field, it must be listed under the Context Field menu. If a field isn't listed, you can add it yourself. See [the how-to guide for creating your own custom fields](../how-to/how-to-define-custom-context-fields) for more info. -::: - -Unleash only provides a limited set of context fields by default, and they may not fulfill all your needs. -By using [custom context fields](../reference/unleash-context#custom-context-fields), you can tailor strategy constraints to your specific use case, such as: -- based on tenant IDs, release a feature to only specific tenants in a multi-tenant setup -- release a feature to users in a specific region -- release a feature only to beta testers - -You can also combine strategy constraints with the [gradual rollout strategy](../reference/activation-strategies#gradual-rollout) to do a gradual rollout to a **specific segment** of your user base. - -![A flag with the gradual rollout strategy. The flag is constrained on the custom content field "region" and set to only activate if the region is Africa or Europe.](/img/strategy-constraints.png) - -## Constraint structure - -Each strategy constraint has three parts: - -- a **context field**: The context field to use for evaluation. -- an **operator**: One of the [operators listed below](#strategy-constraint-operators). -- a **value**/**list of values**: A value or list of values to use in the evaluation of the constraint. - -These parts turn the strategy constraint into an expression that evaluates to either `true` or `false`. - -To clarify, here's a few example strategy constraints and what they do: - -| Context field | Operator | Value(s) | Description | -|-----------------|-----------------|--------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| -| `userId` | `STR_ENDS_WITH` | `@example.com, @mycompany.com` | Evaluates to `true` for users whose user IDs end with `@example.com` or `@mycompany.com`. | -| `currentTime` | `DATE_AFTER` | `2022-06-05 21:43:22Z` | Evaluates to `true` if the current time is after `2022-06-05 21:43:22Z`. | -| `userScore`[^1] | `NUM_GTE` | `1000` | Evaluates to `true` if the [custom context field](../reference/unleash-context#custom-context-fields) `userScore` has a value of `1000` or higher. | - -## Strategy constraint operators - -:::note Placeholder context field -In this section, `` is used as a placeholder for an arbitrary context field. With the exception of the `currentTime` field, you can use any context field in its place. -::: - -Unleash supports a wide range of constraint operators. `IN` and `NOT_IN` are basic operators that are available in all versions and SDKs. All other operators require Unleash version 4.9+ and [SDK compatibility](../reference/sdks#strategy-constraints). - -### Constraint negation / inversion {#constraint-negation} - -All constraint expressions can be **negated**, meaning that they get their opposite value. Constraints are evaluated to either `true` or `false`. Negating a constraint would turn a `true` value into a `false` and a `false` value into a `true` value. - -For instance, using the numeric equivalence operator `NUM_EQ`, the following truth table shows the how value negation affects the result: - -| Expression | Value | Negated | -|--------------|---------|---------| -| 4 `NUM_EQ` 4 | `true` | `false` | -| 4 `NUM_EQ` 5 | `false` | `true` | - - -### Numeric operators - -Numeric operators compare the numeric values of context fields with your provided value. - -Numeric operators only accept single values. - -| Name | `true` if `` is ... | -|-----------|--------------------------------------------------------------------------------| -| `NUM_EQ` | **equal** to the provided value; the mathematical `=` operator | -| `NUM_GT` | **strictly greater than** the provided value; the mathematical `>` operator | -| `NUM_GTE` | **greater than or equal to** the provided value; the mathematical `⩾` operator | -| `NUM_LT` | **strictly less than** the provided value; the mathematical `<` operator | -| `NUM_LTE` | **less than or equal to** the provided value; the mathematical `⩽` operator | - -You can read more about [numeric equality](https://en.wikipedia.org/wiki/Equality_(mathematics) "Mathematical equality at Wikipedia") or [numeric inequality operators at Wikipedia](https://en.wikipedia.org/wiki/Inequality_(mathematics)). - -### Date and time operators - -:::info `currentTime` and date and time operators -The date and time operators are **only available on the `currentTime`** context field. Furthermore, the `currentTime` context field **can not be used** with any of the other operators. -::: - -With the date and time operators, you can enable a feature before and/or after a specified time. -The operators compare the [Unleash context's](../reference/unleash-context) `currentTime` property against the provided value. - -You can create a **time span** by combining the two constraint operators using two different constraints on the same strategy. -In that case the strategy will be evaluated from `DATE_AFTER` and until `DATE_BEFORE`. - -Date and time operators only support single values. - -| Name | `true` if `currentTime` is ... | -|---------------|--------------------------------| -| `DATE_AFTER` | **after** the provided date | -| `DATE_BEFORE` | **before** the provided date | - -### String operators - -String operators differ from the other categories in two different ways: -- all operators accept multiple values -- most operators also consider [letter case](https://en.wikipedia.org/wiki/Letter_case "letter case on Wikipedia") and can be set to be case-sensitive or case-insensitive - -| Name | `true` if `` ... | Supports case-insensitivity | Available since | -|-------------------|------------------------------------------------|-----------------------------|-----------------| -| `IN` | is **equal** to any of the provided values | No | v3.3 | -| `NOT_IN` | is **not equal** to any of the provided values | No | v3.3 | -| `STR_CONTAINS` | **contains** any of the provided strings | Yes | v4.9 | -| `STR_ENDS_WITH` | **ends** with any of the provided strings | Yes | v4.9 | -| `STR_STARTS_WITH` | **starts** with any of the provided strings | Yes | v4.9 | - - -### Versioning (SemVer) operators - -The SemVer operators are used to compare version numbers such as application versions, dependency versions, etc. - -The SemVer input must follow a few rules: -- The value you enter **must** start with and contain at least major, minor, and patch versions: Example: `1.2.3` -- Optionally, you can also add pre-release version information by adding a hyphen and series of dot separated identifiers after the patch version. Example: `1.2.3-rc.2` - -Versions with pre-release indicators (e.g. `4.8.0-rc.2`) are considered *less than* versions without (e.g. `4.8.0`) in accordance with [the SemVer specification, item 11](https://semver.org/#spec-item-11). - -You can read more about SemVer in [the full SemVer specification](https://semver.org/). - -SemVer operators only support single values. - -| Name | `true` if `` is ... | -|-------------|----------------------------------------------| -| `SEMVER_EQ` | **equal** to the provided value | -| `SEMVER_GT` | **strictly greater than** the provided value | -| `SEMVER_LT` | **strictly less than** the provided value | - -Additionally, you can use negation to get _less than or equal to_ and _greater than or equal to_ functionality: - -| Effect | How | `true` if `` is ... | -|--------------------------|--------------------|-------------------------------------------------| -| Greater than or equal to | Negate `SEMVER_LT` | **greater than or equal to** the provided value | -| Less than or equal to | Negate `SEMVER_GT` | **less than or equal to** the provided value | - -"Not less than 2.0.0" _is the same as_ "greater than or equal to 2.0.0". The same applies for _less than or equal_: "Not greater than 1.9.5." _is the same as_ "less than or equal to 1.9.5". - -## Interacting with strategy constraints in the client SDKs {#sdks} - -:::note -This section gives a brief overview over to use the client SDKs to interact with strategy constraints. The exact steps will vary depending on which client you are using, so make sure to consult the documentation for your specific client SDK. -::: - -Strategy constraints require [the Unleash Context](../reference/unleash-context) to work. All official [Unleash client SDKs](../reference/sdks) support the option to pass [dynamic context values](../reference/unleash-context#structure) to the `isEnabled` function (or the SDK's equivalent). - -If the strategy constraint uses a [**standard Unleash Context field**](../reference/unleash-context#structure), set the context field to the value you wish to give it. - -If the strategy constraint uses a [**custom context field**](../reference/unleash-context#custom-context-fields), use the Unleash Context's `properties` field. Use the name of the custom context field as a key and set the value to your desired string. - -If you set a context field to a value that the SDKs cannot parse correctly for a chosen constraint operator, the strategy constraint will evaluate to false. -In other words: if you have a strategy constraint operator that expects a number, such as `NUM_GT`, but you set the corresponding context field to a string value, then the expression will be false: `"some string"` is **not** greater than `5`. -This value can still be negated as explained in [the section on negating values](#constraint-negation). - -## Constraint limitations (or "how many user IDs can I add to a constraint") {#limitations} - -:::tip - -Explore the content in this subsection in more depth in [the topic guide on using Unleash with large constraints](/understanding-unleash/managing-constraints). - -::: - -When using a constraint operator that accepts a list of values, it might be tempting to add a large number of values to that list. However, we advise you **not** to do that: Unleash is not a database, and is not intended to store large amounts of data. Instead you should try and find a different way to achieve what you want. - -For instance, instead of adding hundreds of user ids to the constraint value list, think about what properties those users share. Are they beta testers? Are they premium members? Are they employees? - -Can you map their common feature into an [Unleash context](../reference/unleash-context) property instead and set the constraint on that? If they're beta testers, how about using a `betaTester` property? And likewise, for premium members, you could check to see if their `membership` is `premium`? And if they're employees, maybe you're better off checking whether their user ID ends with `@yourcompany.tld`? - -The **reason** why you should try and keep value lists small has to do with Unleash's evaluation model: Because Unleash's server-side SDKs fetch the full feature flag configuration from Unleash, every value that you add to that constraint value list will increase the payload size. For small numbers, this isn't an issue, but as the list grows, so will the payload, and so will the time and processing power used by the SDK to evaluate the feature. - -## Incompatibilities and undefined behavior {#incompatibilities} - -It's important that you use an up-to-date client SDK if you're using the advanced constraint operators introduced in Unleash 4.9. If your client SDK does not support the new operators, we cannot guarantee how it'll react. As a result, you may see different behavior across applications. - -If you use the new constraints with old SDKs, here's how it'll affect _some_ of the SDKs (the list is not exhaustive): -- The Node.js and Go client SDKs will ignore the new constraints completely: the constraints will not affect the flag's status. -- The Python client SDK will evaluate the flag to false, as it cannot evaluate the constraint successfully. -- The .NET, Ruby, and PHP SDKs raise exceptions if the provided operator is not `IN` or `NOT_IN`. - -Please inspect the [SDK compatibility table to see which version of your preferred SDK introduced support for this feature](../reference/sdks#strategy-constraints). - -After Unleash 4.9, we updated the [Unleash client specification](https://github.com/Unleash/client-specification). Going forward, any constraint that a client does not recognize, **must be evaluated as `false`** - -## [Deprecated]: Constrain on a specific environment {#constrain-on-a-specific-environment} - -Before Unleash 4.3, using strategy constraints was the recommended way to have different flag configurations per environment. Now that Unleash has environment support built in, we no longer recommend you use strategy constraints for this. Instead, see the [environments documentation](../reference/environments). - -[^1]: `userScore` is not a default Unleash field, but can be added as a [custom context field](../reference/unleash-context#custom-context-fields). diff --git a/website/docs/reference/strategy-variants.mdx b/website/docs/reference/strategy-variants.mdx index 2ac817a98154..db0618eec7af 100644 --- a/website/docs/reference/strategy-variants.mdx +++ b/website/docs/reference/strategy-variants.mdx @@ -6,133 +6,92 @@ import VideoContent from '@site/src/components/VideoContent.jsx' :::note Availability -**Version**: `5.4+` +**Version**: `5.4+` and [SDK compatibility](/reference/sdks#server-side-sdk-compatibility-table). ::: +## Overview +Variants let you expose different versions of a feature to users, for example, as part of A/B and multivariate testing. By defining variants, you can extend a feature flag's payload with additional data. +Variants are configured within the feature flag's [activation strategies](/reference/activation-strategies). -Gradual rollout strategies in Unleash can have _strategy variants_. _Strategy variants_ allow each matching activation strategy to return not just simple enabled/disabled status, but -also attach any custom data or even multiple data items. +A variant consists of three components: +- Name: unique identifier for the variant within the strategy. Use this to identify the variant in your clients. +- Weight: The [variant weight](#variant-weight) determines the likelihood of users receiving a specific variant. +- Optional payload: You can add a payload to deliver more data or context. Define this if you want to return data in addition to the `enabled`/`disabled` value of the flag. The payload has: + - Type: The format of the data (`string`, `json`, `csv`, or `number`). + - Value: The data itself, matching the specified type. -## What are strategy variants? +![Adding new strategy variants](/img/strategy-variant-creation-form.png) -Whenever you create a feature activation strategy, you can assign it one or more values called _variants_. -This is commonly done in cases where you want to serve your users additional information related to the matching strategy. -Also it's possible to assign multiple variants to one strategy to see which performs better. +## Variant weight -A variant has four components that define it: -- a **name**: +The weight of a variant specifies how often it will be assigned to users. Weights are numbers between 0 and 100, with up to one decimal place of precision. - This must be unique among the strategy's variants. When working with a feature with variants in a client, you will typically use the variant's name to find out which variant it is. +For multiple variants, the total weight must equal 100. Based on the [weight type](#weight-type), Unleash balances weights automatically. -- a **weight**: +### Weight type - The weight is the likelihood of any one user getting this specific variant. See the [weights section](#variant-weight) for more info. +There are two kinds of variant weight types: variable and fixed. At least one variant must use a variable weight. -- an optional **payload**: +- Variable weight: Adjusts automatically based on other variable weights and "unused" weight from fixed variants, if any. This is the default type. +- Fixed weight: Remains constant regardless of other variants. - A variant can also have an associated payload. Use this to deliver more data or context. See the [payload section](#variant-payload) for a more details. +### Weight calculation example +To calculate what the weight of a variable variant is, Unleash first subtracts the sum of fixed weights from 100 and then distributes the remaining weight evenly among the variable variants. -![A form for adding new strategy variants. It has fields for name, weight, payload.](/img/strategy-variant-creation-form.png 'Creating a new strategy variant') +For instance, if you were to have three variable variants and two fixed variants weighted at 25 and 15 respectively, the process would look like this: +1. Subtract the fixed weight from the total available: 100 - (25 + 15) = 60 +2. Divide the remainder by the number of variable variants: 60 / 3 = 20 +3. Assign each variable variant the same (rounded to one decimal precision) weight: 20 -### Variant weight +## Variant payload -A variant's weight determines how likely it is that a user will receive that variant. It is a numeric value between 0 and 100 (inclusive) with one decimal's worth of precision. - -When you have multiple variants, the sum of all their weights must add up to exactly 100. Depending on the [weight type](#weight-types), Unleash may automatically determine the weight of the new variant and balance it out with the other variants. - -#### Weight types and calculation - -There are two kinds of variant weight types: _variable_ and _fixed_. Unleash requires you to always have _at least_ one variable weight variant. - -The default weight type is _variable_. Variable weight variants will adjust their weight based on the number of other variable weight variants and whatever weight is not used up by fixed weight variants. - -_Fixed_ weight variants have a set weight which will not change. All fixed weight variants' weights can not add up to more than 100. - -To calculate what the weight of a variable weight variant is, Unleash first subtracts the sum of fixed weights from 100 and then distributes the remaining weight evenly among the variable weight variants. - -For instance, if you have three variable weight variants and two fixed weight variants weighted at 25 and 15 respectively, Unleash will: -1. Subtract the fixed weight from the total available: 100 - 40 = 60 -2. Divide the remainder by the number of variable weight variants: 60 / 3 = 20 -3. Assign each variable weight variant the same (up to rounding differences) weight: 20% - -In the example above, 60 divides cleanly by three. In cases where the remainder doesn't divide evenly among the variable weight variants, Unleash will distribute it as evenly as it can to one decimal's precision. If you have three variable weight variants, they will be weighted at 33.4, 33.3, and 33.3 respectively, so that it adds up to 100.0. - -### Variant payload - -Each variant can have an associated payload. Use this to add more context or data to a payload that you can access on the client, such as a customized message or other information. - -Unleash currently supports these payload types: - -- JSON -- CSV -- String +Variants can have an associated payload in a JSON, CSV, number, or string format. You can use this to add more context or data to a payload that you can access on the client. ### Variant stickiness -When you have only one variant in a strategy, stickiness does not matter. If you decide to add multiple variants to the strategy, then variant stickiness is derived from the strategy stickiness. -Strategy stickiness is calculated on the received user and context, as described in [the stickiness chapter](./stickiness.md). This ensures that the same user will consistently see the same variant. If no context data is provided, the traffic will be spread randomly for each request. - -If you would like to reassign users to different variants using existing stickiness parameter then you can change the groupId of the strategy. This will provide different input to the stickiness calculation. +When you have one variant in an activation strategy, stickiness does not matter. In the case of multiple variants, variant stickiness is derived from the stickiness defined on the activation strategy. +[Stickiness](/reference/stickiness) is evaluated based on [context data](/reference/unleash-context) and it ensures that the same user consistently sees the same variant. If no context data is provided, the traffic is spread randomly for each request. -### Strategy variants vs feature flag variants +To reassign users to different variants using an existing stickiness parameter, modify the `groupId` of the activation strategy. This provides a different input to the stickiness calculation. -Strategy variants take precedence over the [feature flag variants](./feature-toggle-variants.md). If your matching activation strategy doesn't have any variants configured you will fall back to the [feature flag variants](./feature-toggle-variants.md). -Since strategy variants are part of activation strategies they have full access to constraints and segments. Feature variants are much more limited since they only allow simple overrides. +## Configure strategy variants -## How do I configure strategy variants +In the Admin UI, go to the feature flag you'd like to define variants for and do the following: +1. Select the environment you want to configure and click **Add strategy**. +2. Go to the **Variants** tab and click **Add variant**. +3. Enter the variant name and an optional payload. +4. Optionally, click **Add variant** again to add more variants. +5. Toggle **Custom percentage** for [fixed weights](#weight-type), if required. +6. Click **Save strategy**. -In the Unleash UI, you can configure variants by navigating to the gradual strategy view, and then choosing the 'Variants' section. -![strategy_variants](/img/strategy-variants.png 'Strategy Variants') +## Fallback variant -## The `disabled` variant - -When your matching strategy has no variants or when your flag has no variants or when a flag is disabled for a user, Unleash will return variant data that looks like this: +If no variant matches in the given context or if the flag is disabled, Unleash returns a fallback variant: ```json { "name": "disabled", - "enabled": false + "enabled": false, + "feature_enabled": false } ``` -This is a fallback variant that Unleash uses to represent the lack of a variant. - -Note: The actual representation of the built-in fallback variant in the client SDK will vary slightly, to honor best practices in various languages. - -## Strategy variants and strategies order - -When you add multiple activation strategies, each having its own variants defined, the order of strategies matters. Unleash chooses the first matching strategy. -It is common to define your specific activation strategies with explicit constraints and segments first. The specific strategies can be followed by a -broad activation strategy with multiple percentage based variants. - -In the example below we configure fixed title for the internal users based on the `clientId` constraint. In the second strategy we split titles between all other users -based on the 50%/50% split. -![strategy_variants example](/img/strategy-variants-example.png 'Strategy Variants example') - -## Client SDK Support {#client-sdk-support} - -To make use of strategy variants, you need to use a compatible client. Client SDK with variant support: +## Activation strategy order -- [unleash-client-node](https://github.com/Unleash/unleash-client-node) (from v4.1.0) -- [unleash-client-java](https://github.com/Unleash/unleash-client-java) (from v8.3.0) -- [unleash-client-go](https://github.com/Unleash/unleash-client-go) (from v3.8.0) -- [unleash-client-python](https://github.com/Unleash/unleash-client-python) (from v5.8.0) -- [unleash-client-ruby](https://github.com/Unleash/unleash-client-ruby) (from v4.5.0) -- [unleash-client-dotnet](https://github.com/Unleash/unleash-client-dotnet) (from v3.3.0) -- [unleash-client-php](https://github.com/Unleash/unleash-client-php) (from v1.13.0) -- Client SDKs talking to [unleash-proxy](https://github.com/Unleash/unleash-proxy) (from v0.17.0) -- Client SDKs talking to Frontend API in [unleash-server](https://github.com/Unleash/unleash) (from v5.4.0) -- Unleash Playground in [unleash-server](https://github.com/Unleash/unleash) (from v5.4.0) +Unleash evaluates activation strategies in order. Therefore, when using multiple activation strategies with variants, define your most restrictive activation strategy first, followed by gradually broader activation strategies. +In the following example, we defined a new checkout flow with two activation strategies: one for internal users matching the company email address, and one for all users. We start by defining the internal activation strategy first, as it is more restrictive. +For this strategy, we defined a variant called `internal-sign-up-flow` that returns the string 'Sign up internally' in the payload. For the second strategy, we defined two variants: `new-sign-up-flow` and `old-sign-up-flow`, that return 'Sign up now' and 'Sign up today' strings respectively. -If you would like to give feedback on this feature, experience issues or have questions, please feel free to open an issue on [GitHub](https://github.com/Unleash/unleash/). +By defining the more restrictive strategy first, we ensure that all internal users get the 'Sign up internally' message, while all other users get a 50-50 split between the 'Sign up now' and 'Sign up today' versions. +![strategy_variants example](/img/strategy-variants-example.png) -## Environment level variants +## Environment-level variants -[Environment level variants](./feature-toggle-variants) are deprecated. Use strategy variants instead. \ No newline at end of file +[Environment-level variants](./feature-toggle-variants) are deprecated. Use strategy variants instead. \ No newline at end of file diff --git a/website/docs/reference/tags.md b/website/docs/reference/tags.md deleted file mode 100644 index 33decb5fc42b..000000000000 --- a/website/docs/reference/tags.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -id: tags -title: Tags ---- - -:::note Availability - -**Version**: `3.11+` - -::: - - -Do you want to filter your features to avoid having to see all features belonging to other teams than your own? Do you want to write a plugin that only gets notified about changes to features that your plugin knows how to handle? - -### Say hello to Typed tags {#say-hello-to-typed-tags} - -Unleash supports tagging features with an arbitrary number of tags. This eases filtering the list of tags to only those features that are tagged with the tag you're interested in. - -#### How does it work? {#how-does-it-work} - -Unleash will allow users to tag any feature with any number of tags. When viewing a feature, the UI will/may display all tags connected to that feature. - -When adding a new tag, a dropdown will show you which type of tag you're about to add. Our first type; `simple` are meant to be used for filtering features. Show only features that have a tag of `MyTeam`. - -#### Tag types {#tag-types} - -Types can be anything, and their purpose is to add some semantics to the tag itself. - -Some tag types will be defined by plugins (e.g. the slack plugin can define the Slack-type, to make it easy to specify which Slack channels to post updates for a specific feature flag to). - -Other tags can be defined by the user to give semantic logic to the management of the UI. It could be that you want to use tag functionality to specify which products a feature flag belongs to, or to which teams. diff --git a/website/docs/reference/technical-debt.md b/website/docs/reference/technical-debt.md index f6e205fdd27a..95e27f9fa9cb 100644 --- a/website/docs/reference/technical-debt.md +++ b/website/docs/reference/technical-debt.md @@ -1,5 +1,6 @@ --- title: Technical Debt +pagination_next: reference/insights --- At Unleash we care deeply about code quality. Technical debt creeps up over time and slowly builds to the point where it really starts to hurt. At that point it's too late. Feature flags that have outlived their feature and are not cleaned up represent technical debt that you should remove from your code. diff --git a/website/docs/reference/unleash-context.md b/website/docs/reference/unleash-context.md index ed84cacb958b..a49e2372d4f9 100644 --- a/website/docs/reference/unleash-context.md +++ b/website/docs/reference/unleash-context.md @@ -2,43 +2,40 @@ title: Unleash Context --- -The **Unleash Context** contains information relating to the current feature flag request. Unleash uses this context to evaluate [activation strategies](activation-strategies) and [strategy constraints](../reference/strategy-constraints) and to calculate [flag stickiness](../reference/stickiness). The Unleash Context is an important feature of all the [Unleash client SDKs](../reference/sdks). +The **Unleash Context** contains information related to the current feature flag request. Unleash uses this context to evaluate [activation strategies](activation-strategies) and [strategy constraints](../reference/activation-strategies#constraints) and to calculate [flag stickiness](../reference/stickiness). The Unleash Context is an important feature of all the [Unleash client SDKs](../reference/sdks). -## Structure +## Overview You can group the Unleash Context fields into two separate groups based on how they work in the client SDKs: **static** and **dynamic** context fields. -**Static** fields' values remain constant throughout an application's lifetime. You'll typically set these when you initialize the client SDK. +**Static** fields remain constant throughout an application's lifetime and are typically set during client SDK initialization. -**Dynamic** fields, however, can change with every request. You'll typically provide these when checking whether a flag is enabled in your client. +**Dynamic** fields can change with each request and are usually provided when checking if a flag is enabled in your client. -_All fields are optional_, but some strategies depend on certain fields being present. For instance, [the UserIDs strategy](activation-strategies#userids) requires that the `userId` field is present on the Context. +All fields are optional, but some strategies depend on certain fields being present. For instance, [the UserID strategy](/reference/predefined-strategy-types#userids) requires that the `userId` field is present on the context. -The below table gives a brief overview over what the fields' intended usage is, their lifetime, and their type. Note that the exact type can vary between programming languages and implementations. Be sure to consult your specific client SDK for more information on its implementation of the Unleash Context. +The following table gives an overview of the fields' intended usage, their lifetime, and their type. The exact type can vary between programming languages and implementations. Check the documentation of your specific client SDK for more information on its implementation of the Unleash Context. | field name | type | lifetime | description | |-------------------|-----------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------| -| `appName` | `string` | static | the name of the application | -| `environment`[^1] | `string` | static | the environment the app is running in | -| `userId` | `string` | dynamic | an identifier for the current user | -| `sessionId` | `string` | dynamic | an identifier for the current session | -| `remoteAddress` | `string` | dynamic | the app's IP address | -| `properties` | `Map` | dynamic | a key-value store of any data you want | -| `currentTime`[^2] | `DateTime`/`string` | dynamic | A `DateTime` (or similar) data class instance or a string in an RFC3339-compatible format. **Defaults to the current time** if not set by the user. | +| `appName` | `string` | static | The name of the application. | +| `environment` | `string` | static | The environment the application is running in. From 4.3+, use [environments](/reference/environments) instead. | +| `userId` | `string` | dynamic | The identifier of the current user. | +| `sessionId` | `string` | dynamic | The identifier of the current session. | +| `remoteAddress` | `string` | dynamic | The application's IP address. | +| `properties` | `Map` | dynamic | A key-value store for additional data. | +| `currentTime` | `DateTime`/`string` | dynamic | A `DateTime` (or similar) data class instance or a string in an RFC-3339 format. **Defaults to the current time** if not set by the user; requires [SDK compatibility](../reference/sdks#strategy-constraints-advanced-support). | ### The `properties` field -The `properties` field is different from the others. You can use the `properties` field to provide arbitrary data to [custom strategies](../reference/custom-activation-strategies) or to [strategy constraints](../reference/strategy-constraints). The `properties` field is also where you add values for [custom context fields](#custom-context-fields). - - -#### A note on properties and constraints +The `properties` field is different from the others. You can use the `properties` field to provide arbitrary data to [strategy constraints](../reference/activation-strategies#constraints) and add values for [custom context fields](#custom-context-fields). Some SDK implementations of the Unleash Context allow for the values in the `properties` map to be of other types than a string type. Using non-string types as values may cause issues if you're using the property in a constraint. Because the Unleash Admin UI accepts any string as input for constraint checking, the SDKs must also assume that the value is a string. As an example: You've created a custom field called `groupId`. You know group IDs will always be numeric. You then create a constraint on a strategy that says the user must be in group `123456`. If you were to set the property `groupId` to the number `123456` in the `properties` field on the SDK side, the constraint check would fail, because in most languages the number `123456` is not equal to the string `123456` (i.e. `123456 != "123456"`). -For operators that work on non-string types, such as numeric and date time operators, these will convert the string value to the appropriate type before performing the comparison. This means that if you use a numeric greater than operator for the value `"5"`, it will convert that value to the number `5` before doing the comparison. If the value can't be converted, the constraint will fail. +For operators that work on non-string types, such as numeric and datetime operators, these will convert the string value to the appropriate type before performing the comparison. This means that if you use a numeric greater than operator for the value `"5"`, it will convert that value to the number `5` before doing the comparison. If the value can't be converted, the constraint will fail. ## Custom context fields @@ -48,22 +45,28 @@ For operators that work on non-string types, such as numeric and date time opera ::: -Custom context fields allow you to extend the Unleash Context with more data that is applicable to your situation. Each context field definition consists of a name and an optional description. Additionally, you can choose to define a set of [_legal values_](#legal-values "legal values for custom context fields"), and you can choose whether or not the context field can be used in [custom stickiness calculations](../reference/stickiness#custom-stickiness) for the [gradual rollout strategy](activation-strategies#customize-stickiness-beta) and for [feature flag variants](../reference/feature-toggle-variants). +Custom context fields allow you to extend the Unleash Context with custom data. Each context field definition consists of a name and an optional description. Additionally, you can define a set of [_legal values_](#legal-values "legal values for custom context fields"), and define if the context field can be used in [custom stickiness calculations](../reference/stickiness#custom-stickiness) for the [gradual rollout strategy](activation-strategies#customize-stickiness-beta) and for [feature flag variants](../reference/feature-toggle-variants). When interacting with custom context fields in code, they must be accessed via the Unleash Context's `properties` map, using the context field's name as the key. -### Creating and updating custom context fields +### Add a custom context field -You can create as many custom context fields as you wish. Refer to ["how to define custom context fields"](../how-to/how-to-define-custom-context-fields) for information on how you define your own custom context fields. +To add a custom context field in the Admin UI, do the following: -You can update custom context fields after they have been created. You can change everything about the definition except for the name. +1. Go to **Configure** > **Context fields** and click **New context field**. +2. Enter a context name. +3. In **Legal value**, enter a value you want the field to support and click **Add**. You can add additional values if needed. +4. Optionally, enable [custom stickiness](/reference/stickiness#custom-stickiness) if you'd like to use this field to group users for a gradual rollout strategy. +5. Click **Create context**. + +Once created, you can modify any aspect of a field’s definition—except its name. You can create as many custom context fields as you need. ### Legal values By using the **legal values** option when creating a context field, you can create a set of valid options for a context field's values. If a context field has a defined set of legal values, the Unleash Admin UI will only allow users to enter one or more of the specified values. If a context field _doesn't_ have any defined legal values, the user can enter whatever they want. -Using a custom context field called _region_ as an example: if you define the field's legal values as _Africa_, _Asia_, _Europe_, and _North America_, then you would only be allowed to use one or more of those four values when using the custom context field as a [strategy constraint](../reference/strategy-constraints). +Using a custom context field called _region_ as an example: if you define the field's legal values as _Africa_, _Asia_, _Europe_, and _North America_, then you would only be allowed to use one or more of those four values when using the custom context field as a [strategy constraint](../reference/activation-strategies#constraints). ![A strategy constraint form with a constraint set to "region". The "values" input is a dropdown menu containing the options "Africa", "Asia", "Europe", and "North America", as defined in the preceding paragraph.](/img/constraints_legal_values.png) @@ -71,14 +74,8 @@ Using a custom context field called _region_ as an example: if you define the fi :::note SDK compatibility -Custom stickiness is supported by all of our SDKs except for the Rust SDK. You can always refer to the [SDK compatibility table](../reference/sdks#server-side-sdk-compatibility-table) for the full overview. +Custom stickiness is supported by all SDKs except for the Rust SDK. Refer to the [SDK compatibility table](../reference/sdks#server-side-sdk-compatibility-table) for more information. ::: -Any context field _can_ be used to [calculate custom stickiness](../reference/stickiness#custom-stickiness). However, you need to explicitly tell Unleash that you want a field to be used for custom stickiness for it to be possible. You can enable this functionality either when you create the context field or at any later point. For steps on how to do this, see [the _How to define custom context fields_ guide](../how-to/how-to-define-custom-context-fields). - - - -[^1]: If you're on Unleash 4.3 or higher, you'll probably want to use [the environments feature](../reference/environments) instead of relying on the `environment` context field when working with environments. - -[^2]: Check the [*strategy constraints: advanced support* row of the compatibility table](../reference/sdks#strategy-constraints-advanced-support) for an overview of which SDKs provide the `currentTime` property. +Any context field _can_ be used to [calculate custom stickiness](../reference/stickiness#custom-stickiness). However, you need to explicitly tell Unleash that you want a field to be used for custom stickiness for it to be possible. You can enable this functionality either when you create a context field or update an existing one. diff --git a/website/docs/understanding-unleash/managing-constraints.mdx b/website/docs/understanding-unleash/managing-constraints.mdx index e74b064a2078..76096802a53f 100644 --- a/website/docs/understanding-unleash/managing-constraints.mdx +++ b/website/docs/understanding-unleash/managing-constraints.mdx @@ -8,7 +8,7 @@ In this explanatory guide, we will discuss how best to deal with large and compl ::: -Unleash offers several ways to limit feature exposure to a specified audience, such as the [User IDs strategy](../reference/activation-strategies#userids), [strategy constraints](../reference/strategy-constraints), and [segments](../reference/segments). Each of these options makes it easy to add some sort of user identifier to the list of users who should get access to a feature. +Unleash offers several ways to limit feature exposure to a specified audience, such as the [User IDs strategy](../reference/predefined-strategy-types#userids), [strategy constraints](../reference/activation-strategies#constraints), and [segments](../reference/segments). Each of these options makes it easy to add some sort of user identifier to the list of users who should get access to a feature. Because of their availability and ease of use with smaller lists, it can be tempting to just keep adding identifiers to those lists. However, once you start approaching a hundred elements, we recommend that you find another way to manage these IDs. In fact, it's probably better to stop well before you get that far. diff --git a/website/docs/understanding-unleash/the-anatomy-of-unleash.mdx b/website/docs/understanding-unleash/the-anatomy-of-unleash.mdx index 472b01646875..a11ad168dbda 100644 --- a/website/docs/understanding-unleash/the-anatomy-of-unleash.mdx +++ b/website/docs/understanding-unleash/the-anatomy-of-unleash.mdx @@ -15,8 +15,8 @@ Some things in Unleash are configured and defined on the root level. These optio - [API access tokens](../reference/api-tokens-and-client-keys) - [Projects](../reference/projects) - [Segments](../reference/segments) -- [Strategy types](../reference/activation-strategies) (including [custom activation strategy types](../reference/custom-activation-strategies)) -- [Tag types](../reference/tags) +- [Strategy types](../reference/activation-strategies) +- [Tag types](../reference/feature-toggles#tags) - [Unleash context](../reference/unleash-context) fields (including [custom context fields](../reference/unleash-context#custom-context-fields)) - Users, [user groups](../reference/rbac#user-groups) and [roles](../reference/rbac) @@ -91,7 +91,7 @@ When you check a [feature flag](../reference/feature-toggles) in an application, Activation strategies tie feature flags and [environments](../reference/environments) together. When you assign an activation strategy to a feature flag, you do so in one environment at a time. You can assign the same strategy to the same flag in different environments, but they will be different instances of the same strategy and do not stay in sync. Unleash also lets you copy strategies from one environment to another. -Unleash comes with a number of [built-in strategies](../reference/activation-strategies). You can also create your own [custom activation strategies](../reference/custom-activation-strategies). All strategies can be further augmented by [**strategy constraints**](../reference/strategy-constraints). +Unleash comes with a number of [built-in strategies](../reference/activation-strategies). All strategies can be further augmented by [**strategy constraints**](../reference/activation-strategies#constraints).