Post Page Advertisement [Top]

 Hello Dear Readers,

As Analog Devices GUI Team, we had a great event this Tuesday. We wrote a Web API that can change its behavior at run-time according to a flag.

As a team, we loved this event and called it a mini-hackathon.

We first understood the problem in the morning. Our problem is as follows: We will write a Web API This API will have an endpoint called getweather. This endpoint will generate three types of random weather reports. Celsius, Fahrenheit and Kelvin. It will decide the type of calculation according to the flag set in the runtime.



We aimed to develop a loosely coupled code without code duplication. We also designed the behavior of enpoint to change when the flag is changed without deploying the code.

After understanding the problem as a team, we started coding. We took a break from our development for lunch and ate together.
After the team members completed their development, everyone presented their solution. We argued over it. Finally, we focused on what is the best apporach.
We are planning to repeat our mini-hackathon, which was very productive and enjoyable. Let's look at the problem together and understand its solution.



WebAPI output The default output when you produce a WebAPI in Visual Studio. We didn't change the script too much to focus on problem solving rather than operation.
First we need to create classes for the Three calculation methods and these classes should derive from an interface.

Below you can see the interface and three different classes. Since it is a question of which of these classes will be decided in run-time, we should use the Factory Design Pattern, so let's create our Factory Class.
 As you can see, according to the flag value, the switch case structure determines which class instance will be created. Here we benefited from .Net's Dependency Injection infrastructure.
 

using FeatureFlaggingDotNet.FeatureFlagging.Domain.Models;

 namespace FeatureFlaggingDotNet.FeatureFlagging.Domain
{
    public interface IWeatherOperation
    {
       IEnumerable<WeatherForecast> GetWeather(string temperatureType);
    }
}


Celcius Calculation :

namespace FeatureFlaggingDotNet.FeatureFlagging.Domain.Services

{

    public class CelsiusOperations : IWeatherOperation

    {

        public IEnumerable<WeatherForecast> GetWeather(string temperatureType)

        {

            return Enumerable.Range(1, 5).Select(index => new WeatherForecast

            {

                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),

                Temperature = (Random.Shared.Next(-20, 55)).ToString() + " " + temperatureType,

                Summary = WeatherTypes.Summaries[Random.Shared.Next(WeatherTypes.Summaries.Length)]

            })

            .ToArray();

        }

    }

}


Factory Class : 

namespace FeatureFlaggingDotNet.FeatureFlagging.Domain

{

    public class WeatherFactory

    {

        private readonly IServiceProvider serviceProvider;

 

        public WeatherFactory(IServiceProvider serviceProvider)

        {

            this.serviceProvider = serviceProvider;

        }

 

        public IWeatherOperation WeatherOperation(string userSelection)

        {

            return userSelection.ToLower() switch

            {

                "celsius" => (IWeatherOperation)serviceProvider.GetService(typeof(CelsiusOperations)),

                "fahrenheit" => (IWeatherOperation)serviceProvider.GetService(typeof(FahrenheitOperations)),

                "kelvin" => (IWeatherOperation)serviceProvider.GetService(typeof(KelvinOperations)),

                _ => throw new NotImplementedException(),

            };

        }

    }

}


Now let's look at how we inject the three classes and the factory class in Program.cs. By injecting dependencies, we leave lifecycle management to .Net dependecy Injection.

 builder.Services.AddSingleton<IFeatureFlagging, FeatureFlagging>();

 builder.Services.AddSingleton<WeatherFactory>();

 builder.Services.AddSingleton<CelsiusOperations>()

            .AddSingleton<IWeatherOperation, CelsiusOperations>(s => s.GetService<CelsiusOperations>());

 builder.Services.AddSingleton<FahrenheitOperations>()

            .AddSingleton<IWeatherOperation, FahrenheitOperations>(s => s.GetService<FahrenheitOperations>());

 builder.Services.AddSingleton<KelvinOperations>()

            .AddSingleton<IWeatherOperation, KelvinOperations>(s => s.GetService<KelvinOperations>());

var app = builder.Build();



Now let's come to the flag issue, we named the central value required for the application as flag. You can keep the flag in the database as well as in appsettings.json, but there are many professional products for Feature Flagging. We preferred to use GrowthBook. The development time is very short and the dashboard is clear and useful.

It is enough to copy the codes produced for you, especially after choosing the application language, which is very easy to integrate into your application.




In addition to turning a feature on or off in your application, you can also use the Feature Flagging method in cases such as A/B Testing, Canary Release, showing the desired feature only to a certain customer group for your application.
And finally, you can access and review the code I wrote for the best approach from my Github account.




I would like to thank Doğuhan Çiftçi and Furkan Koçyiğit in the GUI Team for their participation. To many more hackathons 🙂 together!

Hiç yorum yok:

Yorum Gönder

Bottom Ad [Post Page]