Agile software development met feature toggles

Introductie

Heel vaak gaat het over agile software development waarmee gesproken wordt over “Scrum”, “Kanban”, etc. Als het goed is zouden deze populaire werk methodieken ervoor moeten zorgen dat teams gaan reflecteren en verbeteren, maar dan heb je ook de tools nodig om je softwareproduct op een agile manier te ontwikkelen.

Een typisch kenmerk van een softwareproduct wat echt met een Agile mindset ontwikkeld is, is namelijk het feit dat er vaak en regelmatig gereleased kan worden. Dit doe je door zo veel mogelijk te automatiseren op het gebied van testing en deployment, maar ook door te zorgen dat je kleine stappen kunt maken. Wat je dan dus niet wilt hebben zijn langdurige feature branches.

Iedere ontwikkelaar, in een wat groter team, weet dat het hebben van branches die lang openblijven een vervelend iets is. Je krijgt merge conflicten, maar het houdt soms ook grotere changes tegen want vaak heerst er een mindset: “Laten we eerst die branch nou maar afronden voordat we verder gaan met een andere change”.

Hoe langer een branch open blijft staan hoe groter de kans op merge conflicten en simpelweg conflicterende aanpassingen.

Hoe los je dit op? Het is een mooi streven om branches zo kort mogelijk te laten leven, maar wanneer een feature simpelweg veel tijd kost om helemaal te ontwikkelen dan heb je een uitdaging. Je kunt het werk in kleinere brokken opdelen, maar als het niet acceptabel genoeg is om naar je volledige userbase vrij te geven dan kun je de branch niet mergen naar de branch waarvandaan je released. Feature Toggles bieden hiervoor oplossingen voor.

Wat daarnaast ook speelt is dat je zo snel mogelijk resultaten wilt tonen en testen. Natuurlijk kan dit op een test omgeving, maar wat nou als je feedback wilt ophalen van een select aantal gebruikers? Wat perfect zou zijn is wanneer je dit ook gewoon in productie kunt proberen.

Maar breng je dan gewoon releases uit die half af zijn? Nee, zeker niet!

Op het moment van schrijven zijn we met de development teams binnen Anycoin Direct druk bezig met een grote feature. Dit is niet een feature die binnen enkele dagen gemaakt kan worden. Wat je dan zou kunnen krijgen is dat er een feature branch gemaakt zou worden waar heel lang aan ontwikkeld gaat worden. Als dat het enige was waaraan ontwikkeld zou worden is dat wellicht geen probleem, maar uiteraard gaat alles gewoon door. Er zijn updates om uit te voeren, bug fixes te doen en andere kleinere features die ook ontwikkeld worden.

Wij kiezen ervoor om geen grote, langdurige feature branches te onderhouden. Zo snel mogelijk naar de branch afronden is onze voorkeur. Wij ontwikkelen deze feature stap voor stap en bij iedere release kunnen wij deze feature testen in productie. Zodra de feature op het niveau is om te gaan releasen dan gaan we de feature releasen voor een kleinere beta gebruikersgroep. Komen daar geen bijzonderheden uit? Dan kunnen we ervoor kiezen om een specifiek land of al onze klanten toegang te geven tot deze nieuwe feature.

Feature toggles als oplossing

Je kunt feature toggles gebruiken om functionaliteiten aan of uit te zetten.

  • Is de feature niet compleet? Dan staat de feature uit of alleen vanaf specifieke locaties, ip adressen of gebruikers.
  • Is de feature wel compleet? Dan kun je de feature aan zetten.
  • Is de feature wel compleet, maar zijn we nog niet helemaal zeker van de mogelijke effecten? Dan stellen we de feature voor een klein gedeelte open. Dit kan op basis van percentages, maar bijvoorbeeld ook op basis van een land.

Feature Management

Microsoft heeft d.m.v. de 2 NuGet’s “Microsoft.FeatureManagement” & “Microsoft.FeatureManagement.AspNetCore” een zeer mooie feature management functionaliteit uitgebracht voor ASP.NET ontwikkelaars.

Een eenvoudige feature toggle kan ofwel aan ofwel uitstaan. Echter kun je de “feature toggle” wat dynamischer laten gedragen dan zijn er feature filters.

Een feature filter betekent eigenlijk dat elke keer wanneer een feature toggle gecheckt wordt vanuit een applicatie dit afhankelijk van de context aan/uit kan staan. Je kunt dit bijvoorbeeld gebruiken om afhankelijk van de locatie van de gebruiker de feature toggle aan/uit te zetten. Er zijn 3 verschillen Feature filters mogelijk:

Percentage

Met een Percentage filter kun je ervoor kiezen de feature aan te zetten voor een specifiek percentage. Let hierbij wel op dat dit er bij iedere check een andere waarde terug kan komen. Wil je zorgen dat een gebruiker elke keer een feature wel/niet mag zien dan kun je beter kiezen voor een Targeting filter.

Targeting

Een Targeting filter kun je gebruiken om op basis van specifieke kenmerken zoals een gebruikersgroep of locatie feature toggle aan te zetten. Per groep kun je een percentage specificeren waarmee je kunt kiezen dat een bepaald percentage die voldoet aan de groep de feature te zien krijgt.

Deze filter is een zogenaamde Contextual Filter en gebruikt de request context bij het bepalen of de feature toggle aan moet staan ja of nee. Een perfect voorbeeld hiervoor is bij het gebruik van een percentage binnen deze Targeting filter waarin je zegt dat 50% van de gebruikers de feature mogen gebruiken. Het is niet fijn voor gebruikers om iedere keer een ander resultaat te krijgen. Door kenmerken van de request context te gebruiken krijgt in dit geval de eindgebruiker iedere keer hetzelfde oordeel.

TimeWindow

Een TimeWindow filter kun je gebruiken om op bepaalde tijden de feature toggle aan te zetten. Deze kan natuurlijk ook handig zijn bij speciale “acties” die alleen op bepaalde tijdstippen gelden. Hiermee hoef je dus niet zelf op het specifieke moment aanwezig te zijn om de feature aan en weer uit te zetten.

1 Een voorbeeld hoe dit in je appsettings.json er uit kan zien.

Het gebruik van Feature Toggles

Tot nu toe heb ik het alleen maar gehad over hoe je feature toggles inricht, maar hoe weet je nu in je applicatie of de feature aan staat?

Hiervoor zijn meerdere mogelijkheden waarbij ik me voor nu focus op de 2 meest voor de hand liggende manieren in een ASP.NET Core scenario.

Views

Wanneer je een MVC view hebt kun je gebruik maken van Tag helpers. Eerst moet je de Tag helper registreren in bijvoorbeeld je _ViewImports.cshtml:

Vervolgens kun je de feature tags gebruiken.

Controllers / Actions

Bij je controllers en/of specifieke controller actions kun je simpelweg gebruik maken van een FeatureGate attribute:

Azure App Configuration

Wanneer je feature toggles in een “appsettings.json” hebt staan kan het al voordelen hebben. Maar je moet er, in dit geval, wel aan denken om dit bij een deployment goed te zetten. Wil je in deze situatie de feature toggles aanpassen dan moet er eigenlijk een nieuwe deployment gedaan worden. Idealiter zou je geen nieuwe deployment willen doen en dat hoeft ook niet, wanneer je Azure App Configuration gebruikt.

Azure App Configuration is een service van Azure die het mogelijk maakt om configuratie in de cloud te beheren. Vanuit een .NET perspectief is het een extra configuration provider. Dynamisch configuratie aanpassingen kunnen doen zonder een deployment is alleen al erg fijn, maar deze service biedt ook de mogelijkheid om specifiek feature toggles te beheren.

Gebruik je Azure App Configuration (wat ik zeker aan raad) dan zou je voor development de appsettings.development.json kunnen gebruiken om features te ontwikkelen en voor bijvoorbeeld test, acceptatie & productie de Azure App Configuration te gaan gebruiken voor een dynamische setting.

Conclusie

Feature toggles kunnen een zeer fijne tool zijn om je product agile te blijven ontwikkelen en releasen. Microsoft’s Feature Management library i.c.m. Azure App Configuration is een zeer mooie combinatie. Zit je niet in deze stack dan zijn er ook genoeg andere tools en producten van andere leverancies, maar in een .NET minded wereld zit je hier zeker goed.

Vond je dit verhaal interessant en had je nog wat vragen? Neem gerust contact met me op via LinkedIn: https://www.linkedin.com/in/vhendriks


Vincent Hendriks

Vincent Hendriks is CTO bij Anycoin Direct en een Software Engineer met meer dan 16 jaar ervaring. Vincent heeft een zeer brede ervaring in onderwerpen zoals C#, .NET/.NET Core, Software architectuur, CQRS, Event Sourcing, SQL, Azure, Docker en nog veel meer.