Aug 3, 2022 · 3 minute read
Feature flags are a common technique used in software engineering to easily turn select functionality on or off during runtime.
Ideally these systems don't require any deployment but for the purpose of this tutorial I'm going to be sharing the mechanism I built in about 3 minutes for madepublic.io.
If you need a full on solution I recommend checking out the excellent Fun With Flags library but for my purposes I needed something that I didn't need to configure, that would allow me to hide new functionality from production (that wasn't ready yet) and carry on developing them in dev and test runtimes.
This mechanism requires deployment but since I'm deploying with fly.io, it takes all of 90 seconds to push up my changes which is great for me - I want to spend my time building useful features over tooling.
We want something flexible so lets make sure this mechanism is flexible enough to handle other features I want to do this with in the future.
So I want to essentially not render certain templates or code if a feature is turned off - let's do that.
First, let's define a module that can read from our Application environment variables:
# lib/features.ex defmodule Madepublic.Features do def feature_available?(feature_key) do Application.get_env(:madepublic, :features)[feature_key] end end
For this to work we need to add new variables to our config files, let's use a keyword list so we can define more in the future.
We also want to make sure that we have a default set - I want every environment other than production to have this feature turned on - for that we can use the
config.exs file to specify a default, then change it on a more granular level for production by overriding it in
# config/config.exs config :madepublic, :features, auth: true # config/runtime.exs if config_env() == :prod do config :madepublic, :features, auth: false end
Sweet - we have the feature but we want it to be available to every template we might have.
Let's hope into our
web.ex file and include our new module in our
# lib/madepublic_web.ex defp view_helpers do quote do # all the original imports and aliases import Madepublic.Features # <- New addition end end
Now let's give it a whirl:
# In any of my templates or .heex files <%= if feature_available?(:auth) do %> <%= render "_user_menu.html", assigns %> <% end %>
We have a repeatable, simple feature flag system that we can use to slowly unveil features to our users.
I hope you found this tutorial useful, subscribe to my Substack below for similar content and follow me on Twitter for more Elixir (and general programming) tips.
If you're building a side project I'd also encourage you to take a look at madepublic.io!