Feature Gating part 3 : how can we check the gates?
Feature Gating part 3 : how can we check the gates?

Feature Gating part 3 : how can we check the gates?

2018, Mar 07    

In this article we’ll explore few ways to check if the feature gates are opened or not. This is the third episode of our series about Feature Gating, last time we discussed about the optimal persistence method for the flags.

The first approach is a static config object injected as dependency in the class cTor:

<span class=pl-k>interface</span> <span class=pl-smi>IFoo</span><span class=pl-kos>{</span>
<span class=pl-c1>bar</span><span class=pl-kos>(</span><span class=pl-kos>)</span>:<span class=pl-smi><span class=pl-k>void</span></span><span class=pl-kos>;</span>
<span class=pl-kos>}</span>
<span class=pl-k>interface</span> <span class=pl-smi>FlagsConfig</span><span class=pl-kos>{</span>
<span class=pl-c1>featureX</span>:<span class=pl-smi>boolean</span><span class=pl-kos>;</span>
<span class=pl-kos>}</span>
<span class=pl-k>export</span> <span class=pl-k>class</span> <span class=pl-smi>Foo</span> <span class=pl-k>implements</span> <span class=pl-smi>IFoo</span><span class=pl-kos>{</span>
<span class=pl-en>constructor</span><span class=pl-kos>(</span><span class=pl-k>private</span> <span class=pl-k>readonly</span> <span class=pl-s1>flagsConfig</span>:<span class=pl-smi>FlagsConfig</span><span class=pl-kos>)</span><span class=pl-kos>{</span><span class=pl-kos>}</span>
<span class=pl-k>public</span> <span class=pl-en>bar</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>{</span>
<span class=pl-k>if</span><span class=pl-kos>(</span><span class=pl-smi>this</span><span class=pl-kos>.</span><span class=pl-c1>flagsConfig</span><span class=pl-kos>.</span><span class=pl-c1>featureX</span><span class=pl-kos>)</span><span class=pl-kos>{</span>
<span class=pl-c>/*…….*/</span>
<span class=pl-kos>}</span><span class=pl-k>else</span><span class=pl-kos>{</span>
<span class=pl-c>/*…….*/</span>
<span class=pl-kos>}</span>
<span class=pl-kos>}</span>
<span class=pl-kos>}</span><span class=pl-kos>;</span>
</p>
</p>

It’s simple, easy to implement and does the job. The configuration object can be instantiated in the composition root reading data from whatever is your persistence layer  and you’re done.

Drawbacks? It’ static. That means you cannot vary your flags based on custom conditions (eg. logged user, time, geolocation).

So what can we do? Something like this:

<span class=pl-k>interface</span> <span class=pl-smi>IFeatureService</span><span class=pl-kos>{</span>
<span class=pl-c1>isEnabled</span><span class=pl-kos>(</span><span class=pl-s1>featureName</span>:<span class=pl-smi>string</span><span class=pl-kos>)</span>:<span class=pl-smi>boolean</span><span class=pl-kos>;</span>
<span class=pl-kos>}</span>
<span class=pl-k>export</span> <span class=pl-k>class</span> <span class=pl-smi>Foo</span> <span class=pl-k>implements</span> <span class=pl-smi>IFoo</span><span class=pl-kos>{</span>
<span class=pl-en>constructor</span><span class=pl-kos>(</span><span class=pl-k>private</span> <span class=pl-k>readonly</span> <span class=pl-s1>featureService</span>:<span class=pl-smi>IFeatureService</span><span class=pl-kos>)</span><span class=pl-kos>{</span><span class=pl-kos>}</span>
<span class=pl-k>public</span> <span class=pl-en>bar</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>{</span>
<span class=pl-k>if</span><span class=pl-kos>(</span><span class=pl-smi>this</span><span class=pl-kos>.</span><span class=pl-c1>featureService</span><span class=pl-kos>.</span><span class=pl-en>isEnabled</span><span class=pl-kos>(</span><span class=pl-s>"feature-x"</span><span class=pl-kos>)</span><span class=pl-kos>)</span><span class=pl-kos>{</span>
<span class=pl-c>/*…….*/</span>
<span class=pl-kos>}</span><span class=pl-k>else</span><span class=pl-kos>{</span>
<span class=pl-c>/*…….*/</span>
<span class=pl-kos>}</span>
<span class=pl-kos>}</span>
<span class=pl-kos>}</span><span class=pl-kos>;</span>
</p>
</p>

Replacing the configuration object with a specific service will do the job. This is probably the most common situation and personally I’m quite a fan. The only drawback is the infamous tech debt: very soon the code will be filled with if/else statements. Should we leave them? Remove them? If yes, when? We will discuss in another article a simple strategy for that.

Speaking about strategy, it’s a very interesting pattern that we can exploit:

<span class=pl-k>export</span> <span class=pl-k>class</span> <span class=pl-smi>Foo</span> <span class=pl-k>implements</span> <span class=pl-smi>IFoo</span><span class=pl-kos>{</span>
<span class=pl-en>constructor</span><span class=pl-kos>(</span><span class=pl-k>private</span> <span class=pl-k>readonly</span> <span class=pl-s1>barStrategy</span>:<span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-c1>=></span><span class=pl-smi><span class=pl-k>void</span></span><span class=pl-kos>)</span><span class=pl-kos>{</span><span class=pl-kos>}</span>
<span class=pl-k>public</span> <span class=pl-en>bar</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>{</span>
<span class=pl-smi>this</span><span class=pl-kos>.</span><span class=pl-en>barStrategy</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>;</span>
<span class=pl-kos>}</span>
<span class=pl-kos>}</span><span class=pl-kos>;</span>
<span class=pl-c>// composition root</span>
<span class=pl-k>const</span> <span class=pl-s1>featureService</span>:<span class=pl-smi>IFeatureService</span> <span class=pl-c1>=</span> <span class=pl-k>new</span> <span class=pl-smi>FeatureService</span><span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-kos>,</span>
<span class=pl-en>strategy1</span> <span class=pl-c1>=</span> <span class=pl-kos>(</span><span class=pl-kos>)</span>:<span class=pl-smi><span class=pl-k>void</span></span> <span class=pl-c1>=></span><span class=pl-kos>{</span> <span class=pl-c>/*…strategy 1…*/</span> <span class=pl-kos>}</span><span class=pl-kos>,</span>
<span class=pl-en>strategy2</span> <span class=pl-c1>=</span> <span class=pl-kos>(</span><span class=pl-kos>)</span>:<span class=pl-smi><span class=pl-k>void</span></span> <span class=pl-c1>=></span><span class=pl-kos>{</span> <span class=pl-c>/*…strategy 2…*/</span> <span class=pl-kos>}</span><span class=pl-kos>,</span>
<span class=pl-s1>barStrategy</span>:<span class=pl-kos>(</span><span class=pl-kos>)</span><span class=pl-c1>=></span><span class=pl-smi><span class=pl-k>void</span></span> <span class=pl-c1>=</span> <span class=pl-s1>featureService</span><span class=pl-kos>.</span><span class=pl-en>isEnabled</span><span class=pl-kos>(</span><span class=pl-s>"feature-x"</span><span class=pl-kos>)</span> ? <span class=pl-s1>strategy1</span> : <span class=pl-s1>strategy2</span><span class=pl-kos>,</span>
<span class=pl-s1>foo</span>:<span class=pl-smi>IFoo</span> <span class=pl-c1>=</span> <span class=pl-k>new</span> <span class=pl-smi>Foo</span><span class=pl-kos>(</span><span class=pl-s1>barStrategy</span><span class=pl-kos>)</span><span class=pl-kos>;</span>
</p>
</p>

The idea is to encapsulate the new and the old logic in two classes (lines 10 and 11) and generate a third one which will use the previous featureService to pick the right instance. Finally all you have to do is to inject that class in the consumer and you’re done.  

Next time: this is nice, but is really useful? What do we really get using Feature Gating?

Did you like this post? Then