Skip to content

Latest commit

 

History

History
159 lines (121 loc) · 6.16 KB

USAGE.md

File metadata and controls

159 lines (121 loc) · 6.16 KB

Accessing features

For simple feature checks, there is a FeatureToggle interface. This acts as a mediator for checking feature states within an environment.

use Nusje2000\FeatureToggleBundle\Repository\FeatureRepository;use Nusje2000\FeatureToggleBundle\RepositoryFeatureToggle;

/** @var FeatureRepository $repository */

$toggle = new RepositoryFeatureToggle($repository, 'some-env');

// Fetching features
$toggle->get('feature-name');
$toggle->exists('feature-name');
$toggle->isEnabled('feature-name');
$toggle->isDisabled('feature-name');

// Feature assertions, will throw exceptions if condition is not met
$toggle->assertDefined('feature-name');
$toggle->assertEnabled('feature-name');
$toggle->assertDefined('feature-name');

Configuration reference

nusje2000_feature_toggle:
    logger: 'service_id' # should reference a psr logger or false to disable the logging
    repository:
        cache_adapter: 'adapter_id' # should reference a symfony cache adapter
        fallback:
            environment: 'fallback_service_id' # or 'static' for configured defaults
            feature: 'fallback_service_id' # or 'static' for configured defaults
        service: # when using a custom repository
            environment: 'environment_repository.service_id'
            feature: 'feature_repository.service_id'
        remote: # when using the API of another host
            host: 'host.domain' # the API host
            cache_store: 'service_id' # the service id of the cache store
            base_path: '/api/feature-toggle' # default
        static: false # uses an internal array as storage (changes are therefore not persistent)
    environment: # required when application is a client
        name: 'environment-name' # custom name for the environment
        hosts: [ 'localhost' ] # when using the api, this will be called by the host to invalidate the cache
        features: # list of features, these will be used as default values
            feature_1: true
            feature_2: true
            feature_3: false
            feature_4:
                enabled: true
                description: 'This is a feature with a description!'
        access_control:
            - { path: '^/feature-protected', ips: [ 127.0.0.1 ], port: 8080, features: { some_feature: true } }
            - { path: '^/feature-protected', ips: [ 127.0.0.1 ], features: { some_feature: true } }
            - { path: '^/feature-protected', host: symfony\.com$, features: { some_feature: true } }
            - { path: '^/feature-protected', methods: [ POST, PUT ], features: { some_feature: true } }

Access control

By using access control you can protect http routes from being access if certain requirements are not met.

nusje2000_feature_toggle:
    environment:
        access_control:
            - { path: '^/feature-1-protected', ips: [ 127.0.0.1 ], port: 8080, features: { feature_1: true } }
            - { path: '^/feature-2-protected', ips: [ 127.0.0.1 ], features: { feature_2: true } }
            - { path: '^/feature-3-protected', host: symfony\.com$, features: { feature_3: false } }
            - { path: '^/feature-4-and-5-protected', methods: [ POST, PUT ], features: { feature_4: false, feature_5: true } }

[NOTE] Only the requirements of the first match will be used. The access_control is evaluated from top to bottom.

Defining route requirements
  • path: a regex representing the path that should be protected
  • host: a regex representing the host that should be protected
  • methods: a list of methods that the condition is applied to
  • ips: a list of ip addresses that the condition is applied to
  • port: the port that the condition is applied to
Defining feature requirements
  • features: {feature_1: false}: requires feature_1 to be disabled
  • features: {feature_1: true}: requires feature_1 to be enabled
  • features: {feature_1: true, feature_1: false}: requires feature_1 to be enabled and feature_2 to be disabled
# paths matching "^/feature-1-protected" accessed from ip address "127.0.0.1" and port 8080 should only be accessible if feature_1 is enabled
- { path: '^/feature-1-protected', ips: [ 127.0.0.1 ], port: 8080, features: { feature_1: true } }

# paths matching "^/feature-2-protected" accessed from ip address "127.0.0.1" should only be accessible if feature_2 is enabled
- { path: '^/feature-2-protected', ips: [ 127.0.0.1 ], features: { feature_2: true } }

# paths matching "^/feature-3-protected" accessed via a host matching "symfony\.com$" should only be accessible if feature_3 is disabled
- { path: '^/feature-3-protected', host: symfony\.com$, features: { feature_3: false } }

# paths matching "^/feature-4-and-5-protected" accessed via a method "POST" or "PUT" should only be accessible if feature_4 is disabled and feature_5 is enabled
- { path: '^/feature-4-and-5-protected', methods: [ POST, PUT ], features: { feature_4: false, feature_5: true } }

Caching

nusje2000_feature_toggle:
    repository:
        cache_adapter: 'some_adapter_id'

Using a cache does require a way to invalidate the cache.

services:
    nusje2000_feature_toggle.cache.invalidator:
        class: Nusje2000\FeatureToggleBundle\Cache\FileStoreInvalidator
        arguments:
            - '/path/to/storage'

Loading the host routes

feature_toggle_host:
    resource: '@Nusje2000FeatureToggleBundle/Resources/config/routing/host.xml'

Loading the client routes

feature_toggle_client:
    resource: '@Nusje2000FeatureToggleBundle/Resources/config/routing/client.xml'

CLI

feature-toggle:update

Registers new features to the configured repository.

bin/console feature-toggle:update
bin/console feature-toggle:update --dry-run # will only show actions that will be taken

feature-toggle:cleanup

Will remove features from the repository that do not exist in the default environment.

bin/console feature-toggle:cleanup
bin/console feature-toggle:cleanup --dry-run # will only show actions that will be taken

Advanced usage

Using the API

See host api definition and client api definition for the documentation.