Share this
Feature Toggles on a .Net Core API
by Adam Knight on 05 October 2017
This article is republished from my original Feature Toggles on a .Net Core API post on fantail.io.
This is my second tutorial on feature toggling. You can read the first here.
There are many languages and frameworks to choose from when it comes to back ends - I wanted to make a REST service to deliver all of the Time Entries to my Angular application, and almost every language available has REST server capabilities. I chose to use .Net Core (C#) and Java for my example app. My background is in Java, and I was really interested to see how .Net Core works. If you don't know, .Net Core is Microsoft's cross platform offering - it has the Windows-specific parts taken out and runs on Docker. Linux, MacOSX, and of course Windows too. It can also be compiled on other platforms too, which is very handy.
Today I'll be setting up LaunchDarkly using the .Net libraries - I'll do the Java version later on. LaunchDarkly provides some samples to help you get started, but I wanted to change a few things. Just like I did in the Angular front end, I wanted to use a type to represent my toggles so that the compiler would help me if I misspelled anything, or forgot to remove a toggle from somewhere. In C# this can be done with an Enum:
The Enum can be mapped to the String values used by LaunchDarkly:
In Java Enums can have properties, e.g. String values that can be obtained from each Enum value - I am missing this right now as it would save me having to provide a separate mapping from Enum to (slightly different) String value. There may be a way better C# way of doing this, please let me know if so! Anyway, using this I can set up the rest of the FeatureToggle class:
I want to take advantage of dependency injection for my REST Controller class, so I have a little setup to do in the Startup.cs file. Firstly I created a configuration class for the API key - LaunchDarkly lets you use two Environments with all plans, so you can have different toggles set in Test and Production. I'd like the correct API Key to be used in test and prod, and using .Net's configuration is a good way to do this. First off, the Configuration class:
This matches up with the configuration in my appsettings.json and appsettings.Development.json files:
When I start the REST API I want the correct LaunchDarkly key to be available to my app - and this is done through the Startup.cs class. This is where all the dependency injection, configuration and initialization is done in ASP.Net.
The full class is available here. When this class runs it will bind the LaunchDarkly configuration to an instance of the LaunchDarklyConfig class, and create a singleton FeatureToggle object. It will also inject these objects where they are needed. The LaunchDarklyConfig object is provided automatically to the constructor of the FeatureToggle:
public FeatureToggle(IOptions<LaunchDarklyConfig> optionsAccessor)
and the FeatureToggle itself is provided to the REST Controller:public TimeController(TimeContext timeCtx, FeatureToggle featureToggle)
The full TimeController.cs class is available here, but the main bits are:
The FeatureToggle object gets injected into the Controller on line 18. I store this object and then when Create or Delete Time Entries is called, check it to see if the feature is enabled. This uses the LaunchDarkly client to give me the latest value from the server. If the flags are not enabled I return an error message - a 404 not found, so the caller knows (thinks) there is nothing available. As soon as I toggle the feature, the check passes and the rest of the code runs. Too easy!
So why don't I just deploy this API, then deploy a new version of my web UI that can use the new features? Why fussing around with Feature Toggles at all?
Feature Toggles will take away any coordination problems putting this new feature live might bring up. I can deploy my code and when I am satisfied it is ready, turn on creating or deleting time entries. If it doesn't work for some reason I can immediately turn the feature off without having to roll back my deployment. Later on (when I add logins and not just anonymous users) I can test the feature out in production by steering some people to the new feature. I can even do this by named account or role using LaunchDarkly! Finally using the toggles I can make sure the front and back end are turned on at the same time - no more hoping my back end finishes deploying before my UI! I can deploy in any order, even weeks apart knowing that my API and UI won't accidentally expose this feature until I'm ready.
Next up I want to do a similar post covering how I implemented LaunchDarkly in Java. See you then!
Adam Knight is an Auckland-based Senior Solution Architect in Equinox IT's Cloud business.
Share this
- Agile Development (153)
- Software Development (126)
- Agile (76)
- Scrum (66)
- Application Lifecycle Management (50)
- Capability Development (47)
- Business Analysis (46)
- DevOps (43)
- IT Professional (42)
- Equinox IT News (41)
- Agile Transformation (38)
- IT Consulting (38)
- Knowledge Sharing (36)
- Lean Software Development (35)
- Requirements (35)
- Strategic Planning (35)
- Solution Architecture (34)
- Digital Disruption (32)
- IT Project (31)
- International Leaders (31)
- Digital Transformation (26)
- Project Management (26)
- Cloud (25)
- Azure DevOps (23)
- Coaching (23)
- IT Governance (23)
- System Performance (23)
- Change Management (20)
- Innovation (20)
- MIT Sloan CISR (15)
- Client Briefing Events (13)
- Architecture (12)
- Working from Home (12)
- IT Services (10)
- Data Visualisation (9)
- Kanban (9)
- People (9)
- Business Architecture (8)
- Communities of Practice (8)
- Continuous Integration (7)
- Business Case (4)
- Enterprise Analysis (4)
- Angular UIs (3)
- Business Rules (3)
- GitHub (3)
- Java Development (3)
- Lean Startup (3)
- Satir Change Model (3)
- API (2)
- Automation (2)
- Scaling (2)
- Security (2)
- Toggles (2)
- .Net Core (1)
- AI (1)
- Diversity (1)
- Testing (1)
- ✨ (1)
- August 2024 (1)
- February 2024 (3)
- January 2024 (1)
- September 2023 (2)
- July 2023 (3)
- August 2022 (4)
- August 2021 (1)
- July 2021 (1)
- June 2021 (1)
- May 2021 (1)
- March 2021 (1)
- February 2021 (2)
- November 2020 (2)
- September 2020 (1)
- July 2020 (1)
- June 2020 (3)
- May 2020 (3)
- April 2020 (2)
- March 2020 (8)
- February 2020 (1)
- November 2019 (1)
- August 2019 (1)
- July 2019 (2)
- June 2019 (2)
- April 2019 (3)
- March 2019 (2)
- February 2019 (1)
- December 2018 (3)
- November 2018 (3)
- October 2018 (3)
- September 2018 (1)
- August 2018 (4)
- July 2018 (5)
- June 2018 (1)
- May 2018 (1)
- April 2018 (5)
- March 2018 (3)
- February 2018 (2)
- January 2018 (2)
- December 2017 (2)
- November 2017 (3)
- October 2017 (4)
- September 2017 (5)
- August 2017 (3)
- July 2017 (3)
- June 2017 (1)
- May 2017 (1)
- March 2017 (1)
- February 2017 (3)
- January 2017 (1)
- November 2016 (1)
- October 2016 (6)
- September 2016 (1)
- August 2016 (5)
- July 2016 (3)
- June 2016 (4)
- May 2016 (7)
- April 2016 (13)
- March 2016 (8)
- February 2016 (8)
- January 2016 (7)
- December 2015 (9)
- November 2015 (12)
- October 2015 (4)
- September 2015 (2)
- August 2015 (3)
- July 2015 (8)
- June 2015 (7)
- April 2015 (2)
- March 2015 (3)
- February 2015 (2)
- December 2014 (4)
- September 2014 (2)
- July 2014 (1)
- June 2014 (2)
- May 2014 (9)
- April 2014 (1)
- March 2014 (2)
- February 2014 (2)
- December 2013 (1)
- November 2013 (2)
- October 2013 (3)
- September 2013 (2)
- August 2013 (6)
- July 2013 (2)
- June 2013 (1)
- May 2013 (4)
- April 2013 (5)
- March 2013 (2)
- February 2013 (2)
- January 2013 (2)
- December 2012 (1)
- November 2012 (1)
- October 2012 (2)
- September 2012 (3)
- August 2012 (3)
- July 2012 (3)
- June 2012 (1)
- May 2012 (1)
- April 2012 (1)
- February 2012 (1)
- December 2011 (4)
- November 2011 (2)
- October 2011 (2)
- September 2011 (4)
- August 2011 (2)
- July 2011 (3)
- June 2011 (4)
- May 2011 (2)
- April 2011 (2)
- March 2011 (3)
- February 2011 (1)
- January 2011 (4)
- December 2010 (2)
- November 2010 (3)
- October 2010 (1)
- September 2010 (1)
- May 2010 (1)
- February 2010 (1)
- July 2009 (1)
- April 2009 (1)
- October 2008 (1)