Exploring Feature Flag use AWS AppConfig
Tags: aws, node, appconfig, typescript
Published: 2022-04-15 06:39:13

Hello Everyone!

This week, I learned about AWS AppConfig, especially for Feature Flag. I need feature flags for my applications since I use [Trunk Based Development](https://trunkbaseddevelopment.com/). Let's move on.

## Setup AWS AppConfig

You may setup your AWS AppConfig use this [official guide](https://docs.aws.amazon.com/appconfig/latest/userguide/appconfig-working.html). You need to follow the 6 steps from the guide:

1. Create an AWS AppConfig application
2. Create an environment
3. Create configuration profiles and feature flags
4. Create a deployment strategy
5. Deploying a configuration
6. Retrieving the configuration

In this article, I will focus on step 6 and the code.

## Retrieve the Feature Flag from AWS AppConfig

Before you retrieve the Feature Flag, you will need `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` with appropriate access. I have created a "small library" to call the feature flag and use [AWS SDK for Javascript](https://aws.amazon.com/sdk-for-javascript/).

```ts
import {
  AppConfigDataClient,
  BadRequestException,
  GetLatestConfigurationCommand,
  StartConfigurationSessionCommand,
} from "@aws-sdk/client-appconfigdata";

const client = new AppConfigDataClient({});
let existingToken: string;

const getToken = async (): Promise<string> => {
  const getSession = new StartConfigurationSessionCommand({
    ApplicationIdentifier: process.env.APP_CONFIG_APP_IDENTIFIER,
    ConfigurationProfileIdentifier:
      process.env.APP_CONFIG_CONFIG_PROFILE_IDENTIFIER,
    EnvironmentIdentifier: process.env.APP_CONFIG_ENVIRONMENT_IDENTIFIER,
  });
  const sessionToken = await client.send(getSession);
  return sessionToken.InitialConfigurationToken || "";
};

const featureFlag = async (flag: string): Promise<boolean> => {
  if (!existingToken) {
    existingToken = await getToken();
    console.log(existingToken);
  }
  try {
    const command = new GetLatestConfigurationCommand({
      ConfigurationToken: existingToken,
    });
    const response = await client.send(command);
    let flags: any = {};
    if (response.Configuration) {
      let str = "";
      for (let i = 0; i < response.Configuration.length; i++) {
        str += String.fromCharCode(response.Configuration[i]);
      }
      const allFlag = JSON.parse(str);
      console.log(allFlag);
      flags = Object.assign({}, allFlag);
    }
    return Boolean(flags[flag]?.enabled);
  } catch (err) {
    if (err instanceof BadRequestException) {
      existingToken = await getToken();
      console.log(existingToken);
      // recall
      return featureFlag(flag);
    } else {
      throw err;
    }
  }
};

export default featureFlag;
```

**Code Explanation**: For getting my feature flag, I need to call `GetLatestConfiguration` API. Before I call that API, I need to get my configuration session token (use `getToken`). If you want to check my code. I've published the code in Github and the library to [NPM](https://www.npmjs.com/package/@berviantoleo/feature-flag).

{% github berviantoleo/feature-flag %}

**Note**: Please don't use this for production. This library is still in heavy development and experimental. I want to improve this library before becoming production-ready.

### How to call my library?

* Promise then/catch

```ts
import featureFlag from '@berviantoleo/feature-flag';

featureFlag('try_feature_flag').then((result) => {
  console.log(result);
});
```

You may use `async`/`await` approach too.


* Example output

![Example output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mp28mxk3kivnaj6iwqmd.png)

> Welcome to contribute to my small library/project. :) If you have any inputs, feel free to add them here too.


## What's Next?

I'm going to create a similar library/project for .NET. So stay tuned!

![GIF Try](https://media.giphy.com/media/QynWK4JOwuhxuiGeXv/giphy.gif)

## Thank you

![Thank you](https://source.unsplash.com/32jBfUrGTRg)

<figcaption>Source from <a href="https://unsplash.com/photos/32jBfUrGTRg">unsplash</a></figcaption>