MTS

How to use Gitlab Feature Flags into Angular

11 November, 2021

5 min read

How to use Gitlab Feature Flags into Angular

A small guide to configure Gitlab Feature Flags, Angular and Unleash

A few days ago I decided to use the Gitlab Feature Flags into my Angular project and, while I was reading the official documentation, I found very hard to understand how to implement it and how it works, so I decided to write an “How to”.

What are Feature Flags?

Feature Flags aka Feature Toggles as Martin Fowler explains:

Feature Toggles (often also refered to as Feature Flags) are a powerful technique, allowing teams to modify system behavior without changing code.

And more from Gitlab official documentation:

With Feature Flags, you can deploy your application’s new features to production in smaller batches. You can toggle a feature on and off to subsets of users, helping you achieve Continuous Delivery. Feature flags help reduce risk, allowing you to do controlled testing, and separate feature delivery from customer launch.

So, basically, feature flags helps you to control the rollout of a feature, or enable it only for a specific environment (like develop or testing env) or for a specific list of users.

Deep in dive

The architecture

Gitlab uses Unleash as feature toggles so you have to connect to it. For the backend everything is configured, so you only have to setup the unleash client, for the frontend (like Angular) you have to do some other steps.

Even if Gitlab Cloud provides Unleash, your application cannot connect directly to it (it will respond you with 401 --- Unauthorized), instead you should use an Unleash Proxy in front of Gitlab in order to communicate with it, so you will have this connection schema:

Enable Feature Flag into Gitlab

First of all you have to enable feature flags into Gitlab and it’s very easy to do: you can find it in Deployments > Feature Flags and then click on “New feature flag”.

Here you can configure your feature flag as you needs. I created one, called image tagging and I choosed a strategy to enable it to all users but only in development and testing environments.

Then you can click on “Create feature flag” and the easy part is done.

Unleash Proxy

Now it’s time to configure Unleash Proxy, to do that you needs some info to consent Unleash to connect with Gitlab. Go to Feature Flags page in Gitlab and click on “Configure”. In the pop-up you have all information:

  • API URL: you will use it to connect Unleash Proxy with Gitlab;
  • Instance ID: id of the instance (also this is used to connect Unleash Proxy);

NB: regeneration of Instance ID will break the integration of Unleash Proxy, so if you have to change it remember to update your Proxy with the new one.

To run Unleash Proxy you can use a simple docker:

docker run \
  -e UNLEASH_PROXY_SECRETS=my_secret_for_client \
  -e UNLEASH_URL=https://gitlab.com/api/v4/feature_flags/unleash/1111111 \
  -e UNLEASH_INSTANCE_ID=XXXXXXXX \
  -e UNLEASH_API_TOKEN=YYYYYY \
  -e UNLEASH_APP_NAME=development \
  -p 3000:3000 \
  unleashorg/unleash-proxy:0.4.0

With these enviroment variables:

  • UNLEASH_PROXY_SECRETS: secret chosed by you and used from Angular app;
  • UNLEASH_URL: copy and paste the API URL from the previous pop-up;
  • UNLEASH_INSTANCE_ID: copy and paste the Instance ID from the previous pop-up;
  • UNLEASH_API_TOKEN: Gitlab API Token, you can generate it in you profile (how to configure it).
  • UNLEASH_APP_NAME: in Unleash Proxy you have to use the environment name for App Name, like development or production.

For each environment you have to deploy a new Unleash Proxy.

Now you can run the docker and check if everything it’s works using this curl:

curl http://localhost:3000/proxy -H "Authorization: UNLEASH_PROXY_SECRETS"

Replace UNLEASH_PROXY_SECRETS with your secret and you will get a response like this:

{"toggles":[{"name":"image_tagging","enabled":true,"variant":{"name":"disabled","enabled":false}}]}

Connect Angular

Here we are: connecting the Angular app with the Unleash Proxy.

Unfortunately Unleash doesn’t support Angular officially but you can still use the Javascript Proxy SDK. So you can install it with npm:

npm install unleash-proxy-client

To handle the feature flags and the connection to the proxy you can create an Angular Service like this:

import { Injectable } from '@angular/core';
import { IMutableContext, UnleashClient } from 'unleash-proxy-client';


@Injectable({
  providedIn: 'root',
})
export class FeatureFlagService {
  unleash = new UnleashClient({
    url: `http://localhost:3000/proxy`, // url to Unleash Proxy
    clientKey: `my_secret_for_client`, // secret used in docker env UNLEASH_PROXY_SECRETS
    appName: `development`, // the appName used in docker env UNLEASH_APP_NAME
    environment: `development`, // you can configure it easily in environment.ts and environment.prod.ts
  });

  constructor() {}

  start(): void {
    this.unleash.start();
  }

  stop(): void {
    this.unleash.stop();
  }

  updateContext(contextObj: IMutableContext): void {
    this.unleash.updateContext(contextObj);
  }

  isEnabled(feature: string): boolean {
    return this.unleash.isEnabled(feature);
  }
}

And start the Unleash polling in the app.component.ts :

import { Component, OnInit } from '@angular/core';
import { FeatureFlagService } from 'src/app/shared/services/feature-flag.service';

@Component({
  selector: 'app-root',
  template: `<router-outlet></router-outlet>`,
  styles: [],
})
export class AppComponent implements OnInit {
  constructor(private readonly featureFlagService: FeatureFlagService) {}

  ngOnInit(): void {
    this.featureFlagService.start();
  }
}

Check a feature

So, if you want to check if a feature is enabled (according with the strategy used) you can use it in this way:

import { Component, OnInit } from '@angular/core';
import { FeatureFlagService } from 'src/app/shared/services/feature-flag.service';

@Component({
  selector: 'app-image',
  templateUrl: 'image.component.html',
  styles: [],
})
export class ImageComponent implements OnInit {
  constructor(private readonly featureFlagService: FeatureFlagService) {}

  ngOnInit(): void {
    if (this.featureFlagService.isEnabled('image_tagging')) {
      // Do something
    } else {
      // Do something else
    }
  }

}

Conclusions

In this way you can activate or deactivate features or you can control the rollout of some features, even provide new features to a part of testing team.

That’s all folks!

Credits

Featured image from Pros and how to use feature flags explained and explored.

Related posts

Build REST API with Apigee and gRPC

Build REST API with Apigee and gRPC

How to build REST API in a few minute using Google Apigee and gRPC

01 December, 2021