Feature Flags and Doctrine Entities

I was in a discussion with some of the EasyBib developers this week about how to use feature flags with Doctrine Entities, Metadata Mapping and their database.

The problem of feature flags with Doctrine is easily explained: If you add properties for a new feature that is disabled in the Doctrine metadata, then you need to upgrade the database before deployment, even when the feature is not being rolled out for some days/weeks. Doctrine requires the database to look exactly like the metadata specifies it.

You can get around this problem by using the loadClassMetadata event quite easily:

<?php
namespace MyProject\Listener;

use MyProject\Config\FeatureFlagConfiguration;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;

class FeatureFlagMetadataListener
{
    private $featureFlagConfiguration;

    public function __construct(FeatureFlagConfiguration $config)
    {
        $this->featureFlagConfiguration = $config;
    }

    public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
    {
        $classMetadata = $eventArgs->getClassMetadata();

        if ($this->featureFlagConfiguration->isEnabled('super_feature2')) {

            if ($classMetadata->name === "MyProject\\Entity\\User") {
                $classMetadata->mapField(array(
                    'fieldName' => 'superFeatureProperty',
                    'type' => 'string'
                ));
            }

            if ($classMetadata->name === "MyProject\\Entity\\Something") {
                // more mapping
            }
        }
    }
}

You can find documentation on the ClassMetadata in the documentation or API.

Then if the feature is enabled fore some time and accepted into the pool of permanent features, you can remove the listener and move the mapping onto the Entities metadata.

More about: Doctrine / ApplicationDesign

Sign up for my newsletter to get notified when I post new content on this blog and with the occasional exclusive content only for subscribers.

By clicking on the Subscribe button I am giving my consent for Benjamin Eberlei to hold my name and email address for the purposes of contacting me with a newsletter on the topics of this blog. You can unsubscribe with one click at any time and withdraw your consent. No spam. I will never share your e-mail address. Privacy Policy