Showing posts with label LaunchDarkly. Show all posts
Showing posts with label LaunchDarkly. Show all posts

Wednesday, October 31, 2018

Feature Toggling Graphql Service with LaunchDarkly

For a project I was working on, we have a graphql service that retrieves clients positions from a SQL database. Under the hood there are some complex SQL stored procedures joining multiple SQL tables and complex data processing before they are finally in a usable shape. We want to move all this complexity to a Hive Big Data project which is more suitable to handle this type of data massaging and have our project consumed a Hive REST API.

The plan is to make sure that once the Hive REST API is live or even during UAT, the consumers of our graphql service do not notice any difference. And if something goes wrong with Hive, we can switch back to good old SQL with very minimal code change. This is where I think LaunchDarkly comes in handy as a fallback scenario. Fortunately I have some prior experience working with it.


The Toy Example

Now to illustrate what I'm dealing with, I have created a toy graphql service. Suppose we have a graphql query that retrieve clients positions defined as:

   type Query {
      positions: [String]
   }

Suppose the result of the query sourced from SQL is:

   {
     "data": {
       "positions": [
         "Sql1",
         "Sql2",
         "Sql3"
       ]
     }
   }

We want to be able to switch to Hive on the fly so that the same query returns:

   {
     "data": {
       "positions": [
         "Hive1",
         "Hive2",
         "Hive3"
       ]
     }
   }

Without feature toggling management, one way to achieve this is to introduce a boolean flag ie. use Hive vs use SQL. The graphql query definition becomes something like this:

   type Query {
      positions(useHive:Boolean!): [String]
   }

This solution isn't always possible because this means we have to change our public API. With LaunchDarkly there's no need to alter our public API, all the code needed for feature toggling happens internally.

Source Code

Using LaunchDarkly

If you're new to LaunchDarkly, see my other post for some background information how to get started.

Create a new feature flag and call it 'position-hive'. When this feature is switched ON, we'll make the positions query returning data from Hive. We can also target a specific set of users who are allowed to use this feature and another set who aren't.

Since I'm using node.js to build this graphql service, we will need LaunchDarkly SDK for Node.js. Install the Node.js SDK with npm:

    npm install ldclient-node --save

We want to make sure that LaunchDarkly client and user are initialised only once when the graphql service started. Once they are initialised, we passed them into the graphql context so we can retrieve these back when needed. Now in the real world there's usually user authentication and authorisation before we can use a service. I'm not going to cover that here, I'm just assuming that's already happening automagically and we can get the user id and name from the graphql request argument.

According to LaunchDarkly SDK documentation, the LaunchDarkly client will emit a 'ready' event when it has been initialized and can serve feature flags. waitForInitialization() function is an alternative to this 'ready' event. If your application uses promises to manage asynchronous operations, which is the case here, this is the recommended way to interact with the SDK. When LaunchDarkly client is ready and can serve feature flags then retrieving a flag setting for a given user can be done this way:

   ldClient.variation(FEATURE_KEY, ldUser, FEATURE_DEFAULT)
     .then(function(featureValue) {
         // application code
     });
The FEATURE_KEY is 'position-hive' and FEATURE_DEFAULT is either true or false. I set it to false in our case as I want our graphql service to use SQL data by default.

Source Code

https://github.com/velianarie/graphql-launchdarkly

Wednesday, May 31, 2017

Feature Toggling with LaunchDarkly

Feature toggle is a software development technique allowing developers to modify system behaviour during run time without code change[1]. Feature toggle is used to enable or disable features. We can for example enable some features for testing even before they are ready for release, but disabled these same features in production.

LaunchDarkly is a feature flag rather than a feature toggle[2]. A toggle implies a two-state condition while a flag can return multiple states or values. In this blog I’m just going to show you how to use LaunchDarkly as a feature toggle to keep things simple.

Project environments

By default LaunchDarkly provides 2 environments, Production and Test. This can be managed in Account settings.

Feature flags

Create a new feature flag by entering:

  • Name
  • Key
  • Description (optional)
  • Flag type

Note that Key is generated automatically as we type in Name. We can alter this if we’re not happy with the auto generated Key. Before saving the flag, please make sure you’re happy with the Key representation. As far as I’m aware, there’s no way we can edit the Key once the flag is created. We will need to delete the whole flag and create a new one with the desirable Key representation. The Key is important here as it is going to be used in your application.

Using LaunchDarkly in your C# application

  1. First thing you need to do is install LaunchDarkly SDK using NuGet in the appropriate project of your C# solution.
  2. Install-Package LaunchDarkly.Client
  3. Import the LaunchDarkly package to your class.
  4. using LaunchDarkly.Client;
  5. Create a new LdClient with your environment-specific SDK key. I'm using Production SDK key here.
  6. var client = new LdClient("sdk-123a4bcd-5ef6-78g0-hi12-34j56k7890l1");
  7. Create a user. I'm only interested in the user name and machine name. You can adjust this according to your need.
  8. var user = User.WithKey(System.Environment.UserName)
                   .AndSecondaryKey(System.Environment.MachineName);
  9. Retrieve LaunchDarkly toggle value.
  10. var isEnabled = client.BoolVariation("calc-scenario-mappings-crud-buttons", user);
    isEnabled returns true if the feature flag is switched ON and returns false if the feature flag is switched OFF.
  11. Use this isEnabled value where you want to enable or disable features in your application.
  12. I'm using LaunchDarkly in a WPF application called CALC to disable the CRUD buttons in Scenario Mappings screen. I already have a view model with a logic that determines whether the CRUD buttons need to be enabled or disabled, so all I need to do is just append this boolean value to the existing logic.

Dev console and run result

Dev console is a handy event listener, it’ll show events as they stream in, live. Have this console open before you run your application.

I’ll run CALC with the feature flag first switched OFF and then switched ON so we can see the different effects.

On the left tab, we see that when the flag is switched OFF, the CRUD buttons are all disabled. On the right tab, when the flag is switched ON, the CRUD buttons are enabled.

Note that the reason why the Dev console show 2 events is because we have 2 tab items (Index and Curve) in the Scenario Mappings screen.