Confeature
is a generic and simple Elixir library to handle your application-wide feature settings, storing them with Ecto and providing a cache interface.
Please note that this is a very early development, and that Confeature
hasn't been tested a lot in production yet.
Also, if you're looking for feature flags that you may apply on groups or actors, you should definitely use :fun_with_flags
instead.
The scope of Confeature
is primarily set on:
- Allowing you to change your application settings dynamically,
- Setting any value at runtime,
- Type-checking updates with structs and specs.
Documentation is available on https://hexdocs.pm/confeature.
Add confeature
to your dependencies:
def deps do
[
{:confeature, "~> 0.1.1"}
]
end
Start by creating Confeature table:
mix ecto.gen.migration create_confeature_table
And use Confeature provided migration:
defmodule YourEctoMigration do
def up do
Confeature.Migration.up()
# or optionally:
Confeature.Migration.up(table_name: "my_features")
end
def down do
Confeature.Migration.down()
# or optionally:
Confeature.Migration.down(table_name: "my_features")
end
end
Declare your Confeature interface
defmodule MyApp.Confeature do
use Confeature,
ecto_repo: MyApp.Repo,
table_name: "my_features", # Optional
cache: MyApp.Cache.Feature # Optional
end
You can check the documentation for implementing a cache store that'll avoid querying your database on each call.
Then, declare a feature, like this:
defmodule MyApp.Features.Throttling do
defstruct [:identifier, :threshold]
@type t :: %__MODULE__{
identifier: string(),
threshold: integer()
}
end
Let's say that you'd want to initialize it in an Ecto migration:
mix ecto.gen.migration init_throttling_settings
defmodule YourMigration do
def up do
MyApp.Confeature.set(%MyApp.Features.Throttling{
identifier: "token",
threshold: 500 # 500 requests
})
end
def down do
MyApp.Confeature.delete!(MyApp.Features.Throttling)
end
end
You can then reference it in your code:
# Retrieve settings
iex> MyApp.Confeature.get(MyApp.Features.Throttling)
%MyApp.Features.Throttling{identifier: "token", threshold: 500}
iex> MyApp.Confeature.set(%MyApp.Features.Throttlin{identifier: "token", threshold: 1000})
%MyApp.Features.Throttling{identifier: "token", threshold: 1000}
Confeature upserts one row per feature in your RDBMS, using a json field to store attributes.
You can also declare a :enabled
attribute, so your feature can be enabled and disabled at runtime:
defmodule MyApp.Features.Throttling do
defstruct [:enabled, :identifier, :threshold]
@type t :: %__MODULE__{
enabled: boolean(),
identifier: string(),
threshold: integer()
}
end
MyApp.Confeature.enabled?(MyApp.Features.Throttling)
MyApp.Confeature.enable(MyApp.Features.Throttling)
MyApp.Confeature.disable(MyApp.Features.Throttling)