What are we trying to do
Let's assume you know about feature flags and are ready to use them in your
project. We need some method to persist decision paths for our user; something
has to keep track if FeatureA
is enabled and FeatureB
is disabled. There are
several options for tracking and toggling features. The spectrum of when these
flags are set ranges from build time to run time. You can hard-code variables in
code (FeatureA = True
). On the other side of the spectrum, you can
decouple releases from deployments. There are hosted feature flipper services like
LaunchDarkly that offer a console to activate flags.
For this tutorial let's use a persistence method that's somewhere in the middle. Let's set a cookie in a user's browser that we check to toggle feature flags. For this tutorial we'll create a view with Django and Django REST Framework. This view sets a cookie that's useful for features and redirects a user to a variable URL.
Defining Our View
A great part about cookie-based feature flags is that we can deploy code and deliver value to users in production. Let's create an endpoint that sets a cookie for a user. The purpose of this cookie is to enable a feature. We'll also redirect the user to a URL we choose; presumably the URL where they'll see the flagged feature in action.
# flags/views.py
from django.shortcuts import redirect
from rest_framework import serializers
FEATURES = {"new-home-page": False}
class FeatureFlagException(Exception):
pass
class CookieFlagSerializer(serializers.Serializer):
feature_name = serializers.CharField()
enable = serializers.ChoiceField(choices=("true", "false"))
duration = serializers.IntegerField(min_value=0, max_value=365 * 24 * 3600)
redirect_url = serializers.URLField()
Let's break this down. FEATURES
is a dictionary where keys are feature
names and values are the features default state: on or off mapping to
True
or False
. While we don't use the default on/off state
in this post, you can see it in action in this follow-up post.
We use the class CookieFlagSerializer
to validate the attributes of
our feature flag. The attributes are few, but useful:
feature_name
- What we're calling the feature. Matches a key inFEATURES
.enable
- Allows us to toggle a feature on and off.duration
- Seconds until the cookie expires and no longer affects the user.redirect_url
- We'll redirect the user to this URL after the cookie is set.
Setting a cookie
We set the cookie in a basic Django view with a few guards around feature flags. We use the serializer we defined above to validate the flag parameters:
# flags/views.py (continued)
def set_cookie_flag_view(request, feature_name):
serializer = CookieFlagSerializer(
data={
"feature_name": feature_name,
"enable": request.GET.get("enable"),
"duration": request.GET.get("duration"),
"redirect_url": request.GET.get("redirect_url"),
}
)
serializer.is_valid(raise_exception=True)
feature_name = serializer.validated_data["feature_name"]
if feature_name not in FEATURES:
raise FeatureFlagException(f"{feature_name} is not a valid feature flag.")
cookie_name = f"features.{feature_name}"
cookie_value = serializer.validated_data["enable"]
cookie_duration = serializer.validated_data["duration"]
redirect_url = serializer.validated_data["redirect_url"]
response = redirect(redirect_url)
response.set_cookie(cookie_name, cookie_value, max_age=cookie_duration)
return response
This, along with a URL configuration like the following are all you need to to create a view that's useful for cookie-based feature flags:
# flags/urls.py
from django.urls import path
from .views import set_cookie_flag_view
path("features/<slug:feature_name>/", set_cookie_flag_view)
Now I can go to a URL like the following and have a feature flag cookie dropped in my browser and be redirected to the flagged URL (we're using the AD home page as an example):
https://accelerate.delivery/features/new-home-page/?enable=true&duration=86400&redirect_url=https://accelerate.delivery
You can respond to this cookie in front-end and back-end code. You can toggle individual lines of code or entire views.
If you're ready for the next, simple step, read our article: Toggling Views with Cookies in Django