stogon / unleash-bundle
Unleash SDK implementation for Symfony framework
Installs: 49 170
Dependents: 0
Suggesters: 0
Security: 0
Stars: 10
Watchers: 3
Forks: 7
Open Issues: 1
Type:symfony-bundle
Requires
- php: ^7.4|^8.0
- lastguest/murmurhash: ^2.1
- symfony/cache-contracts: ^2.4|^3.0
- symfony/config: ^5.4|^6.4|^7.0
- symfony/console: ^5.4|^6.4|^7.0
- symfony/dependency-injection: ^5.4|^6.4|^7.0
- symfony/event-dispatcher-contracts: ^2.4|^3.0
- symfony/http-client-contracts: ^2.4|^3.0
- symfony/http-kernel: ^5.4.20|^6.4|^7.0
- symfony/security-core: ^5.4|^6.4|^7.0
- twig/twig: ^2.12|>=3.11.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.64
- phpstan/phpstan: ^1.12.0
- phpunit/phpunit: ^9.6
- psr/log: ^1|^2|^3
- symfony/var-dumper: ^5.4|^6.4|^7.0
README
An Unleash bundle for Symfony 5.4+, 6.4+ and 7.0+ applications.
This provide an easy way to implement feature flags using Gitlab Feature Flags Feature.
This implementation conforms to the official Unleash standards.
Inspired by minds/unleash-client-php and mikefrancis/laravel-unleash.
Installation
composer require stogon/unleash-bundle
Configurations
Full configurations example:
# config/packages/unleash.yaml unleash: # The full URL to your unleash-server instance (must end with a slash). # Example with the "feature_flags" feature from Gitlab.com : https://gitlab.com/api/v4/feature_flags/unleash/<project_id>/ api_url: 'https://gitlab.com/api/v4/feature_flags/unleash/<project_id>/' # Authorization key if needed auth_token: '<auth>' # Instance ID of your unleash application. # Example : VPQgqIdAxQyXY96d6oWj instance_id: '<some ID>' # Unleash application name. # For Gitlab feature flags, it can be set to the environment name. # default: '%kernel.environment%' environment: '%kernel.environment%' cache: # Enable caching of features fetched from Unleash server. # default: true enabled: true # Service ID to use for caching (must be a cache pool) # default: '%unleach.cache.service%' (which resolve to '@cache.unleash.strategies' service) service: '@cache.app' # The period of time from the present after which the item MUST be considered expired in the cache in seconds # default: 15 ttl: 15
Usage
To use the client, simply inject Stogon\UnleashBundle\UnleashInterface
into your service and use it like this:
<?php namespace App\Controller; use Stogon\UnleashBundle\UnleashInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class HomeController extends AbstractController { #[Route('/', name: 'homepage')] public function index(UnleashInterface $unleash): Response { if ($unleash->isFeatureEnabled('my_awesome_feature')) { // do something awesome ! } if ($unleash->isFeatureDisabled('my_other_feature')) { // do something else } return $this->render('home/index.html.twig'); } }
Twig
The bundle also provide Twig functions to check if a feature is enabled/disabled for the current user:
{# Check if a feature is enabled for current user #} {%- if is_feature_enabled('my_awesome_feature') -%} <div class="alert alert-success" role="alert"> The <code>my_awesome_feature</code> feature is enabled for current user ! </div> {%- else -%} <div class="alert alert-warning" role="alert"> The <code>my_awesome_feature</code> feature is disabled for current user ! </div> {%- endif -%} {# Check if a feature is disabled for current user #} {%- if is_feature_disabled('my_awesome_feature') -%} <div class="alert alert-success" role="alert"> The <code>my_awesome_feature</code> feature is disabled for current user ! </div> {%- else -%} <div class="alert alert-warning" role="alert"> The <code>my_awesome_feature</code> feature is enabled for current user ! </div> {%- endif -%}
Console
There are console commands that comes with this bundle :
Command name | Description |
---|---|
unleash:features:fetch |
Fetch Unleash features from remote and store them in the cache for later usage. |
unleash:features:list |
List available Unleash features from remote. |
Strategies
Available strategies:
Strategy name | Description |
---|---|
default |
It is the simplest activation strategy and basically means "active for everyone". |
userWithId |
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.) |
flexibleRollout |
A flexible rollout strategy which combines all gradual rollout strategies in to a single strategy (and will in time replace them) |
gradualRolloutUserId |
The gradualRolloutUserId strategy gradually activates a feature toggle 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 |
gradualRolloutSessionId |
Similar to gradualRolloutUserId strategy, this strategy gradually activates a feature toggle, 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. |
gradualRolloutRandom |
The gradualRolloutRandom strategy randomly activates a feature toggle 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. |
For more informations, see https://docs.getunleash.io/docs/activation_strategy
Add a custom strategy
If the existing strategies does not fill your needs, you can implement a custom strategy with your own logic.
First, you need to create a class which implements the Stogon\UnleashBundle\Strategy\StrategyInterface
<?php namespace App\Unleash\Strategy; use Stogon\UnleashBundle\Strategy\StrategyInterface; class MyCustomStrategy implements StrategyInterface { public function isEnabled(array $parameters = [], array $context = [], ...$args): bool { // TODO: Implement your custom logic here. return false; } }
Then you need to tag your custom strategy with the unleash.strategy
tag and provide a activation_name
for it.
services: App\Unleash\Strategy\MyCustomStrategy: tags: - { name: unleash.strategy, activation_name: my_custom_activation_strategy }
The
activation_name
must match thestrategy.name
value of your Unleash strategy ! see https://docs.getunleash.io/docs/activation_strategy
Override an existing strategy
You can override an existing strategy simply by setting the activation_name
of the tag
to the same strategy name used here.
Example:
services: App\Unleash\Strategy\MyCustomStrategy: tags: - { name: unleash.strategy, activation_name: userWithId }
Add additional context to strategies
If you want to add additional data to the context passed to resolved strategy ($context
parameter of the Stogon\UnleashBundle\Strategy\StrategyInterface::isEnabled
method), you can implement an event listener/subscriber to react to the Stogon\UnleashBundle\Event\UnleashContextEvent
event.
Example:
<?php namespace App\EventSubscriber; use Stogon\UnleashBundle\Event\UnleashContextEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class UnleashContextSubscriber implements EventSubscriberInterface { public static function getSubscribedEvents(): array { return [ UnleashContextEvent::class => ['onUnleashContextEvent'], ]; } public function onUnleashContextEvent(UnleashContextEvent $event): void { // Get the original payload as an array; $payload = $event->getPayload(); // Set some custom data $payload['awesome_data'] = 'amazing'; // Update payload $event->setPayload($payload); } }
Testing
Simply run :
composer run test
or
$ ./vendor/bin/phpunit
$ ./vendor/bin/phpstan analyse
$ ./vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php
Contributing
See CONTRIBUTING.md.