aubes/openfeature-configcat-bundle
Install the bundle:
composer require aubes/openfeature-configcat-bundle
Manually register the bundle in config/bundles.php if Symfony Flex isn't used:
Aubes\OpenFeatureConfigCatBundle\OpenFeatureConfigCatBundle::class => ['all' => true],
Configure the bundle in config/packages/open_feature_configcat.yaml:
open_feature_config_cat:
sdk_key: '%env(CONFIGCAT_SDK_KEY)%'
Ensure CONFIGCAT_SDK_KEY is set in your .env file.
First use case: Fetch a feature flag in a service:
use ConfigCat\OpenFeature\ConfigCatProvider;
use OpenFeature\OpenFeatureAPI;
class FeatureService {
public function __construct(private ConfigCatProvider $provider) {}
public function toggleDarkMode(): bool {
return OpenFeatureAPI::getInstance()
->setProvider($this->provider)
->getClient()
->getBooleanValue('dark_mode', false);
}
}
ConfigCatProvider directly into services for OpenFeature API access.If using aubes/openfeature-bundle, configure it to use this provider:
# config/packages/open_feature.yaml
open_feature:
provider: ConfigCat\OpenFeature\ConfigCatProvider
This unlocks:
#[FeatureFlag], #[FeatureGate]).feature_flag()).Use local overrides for development/testing:
open_feature_config_cat:
flag_overrides:
type: file
path: '%kernel.project_dir%/config/feature_flags.json'
behaviour: local_over_remote # Overrides remote flags
Replace Guzzle with Symfony’s HttpClient (PSR-18):
# config/services.yaml
services:
Aubes\OpenFeatureConfigCatBundle\Http\Psr18FetchClient:
arguments:
$client: '@psr18.http_client'
$requestFactory: '@Psr\Http\Message\RequestFactoryInterface'
# config/packages/open_feature_configcat.yaml
open_feature_config_cat:
fetch_client: Aubes\OpenFeatureConfigCatBundle\Http\Psr18FetchClient
Missing SDK Key:
sdk_key is omitted, the provider will fail silently. Validate in config/validator.yaml:
services:
_defaults:
autowire: true
bind:
ConfigCat\OpenFeature\ConfigCatProvider::class: '@open_feature_config_cat.provider'
if (empty($provider->getSdkKey())) {
throw new \RuntimeException('ConfigCat SDK key not configured.');
}
Caching Conflicts:
cache and cache_pool in config. They are mutually exclusive.Offline Mode:
offline: true for development, but ensure flag_overrides are configured to avoid empty flag evaluations.Enable Logging:
open_feature_config_cat:
logger: '@monolog.logger.configcat'
Logs will include flag evaluation details and fetch errors.
Check Cache:
If flags aren’t updating, verify the cache_refresh_interval (default: 60s) and clear the cache:
php bin/console cache:clear
Custom Fetch Client:
Implement ConfigCat\Http\FetchClientInterface for custom HTTP logic (e.g., retries, proxies).
Override Data Sources: For dynamic overrides, inject a service:
open_feature_config_cat:
flag_overrides:
type: service
id: 'app.feature_flag_override_service'
Data Governance:
Use data_governance: eu_only to comply with GDPR by hosting data in the EU.
getBooleanValues(), getStringValues(), etc., to fetch multiple flags in one request.OpenFeatureAPI::getInstance()->setProvider($provider);
$provider = $this->createMock(ConfigCatProvider::class);
$provider->method('getBooleanValue')->willReturn(true);
OpenFeatureAPI::getInstance()->setProvider($provider);
offline: true and flag_overrides to avoid network calls.
How can I help you explore Laravel packages today?