# FlagsmithEngine
Documentation: [https://hexdocs.pm/flagsmith_engine](https://hexdocs.pm/flagsmith_engine)
<div align="center">
<a href="#installation">Installation</a><span> |</span>
<a href="#usage">Usage</a><span> |</span>
<a href="#options">Options</a><span> |</span>
<a href="#internals">Internals</a><span> |</span>
</div>
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `flagsmith_engine` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:flagsmith_engine, "~> 0.1.0"}
]
end
```
## Usage
You can configure this library by setting on the relevant config file:
```elixir
config :flagsmith_engine, :configuration,
environment_key: "<YOUR SDK KEY>",
api_url: "https://api.flagsmith.com/api/v1>",
default_flag_handler: function_defaults_to_not_found,
custom_headers: [{"to add to", "the requests"}],
request_timeout_milliseconds: 5000,
enabled_local_evaluation: false,
environment_refresh_interval_milliseconds: 60_000,
retries: 0,
enable_analytics: false
```
Any field `t:Flagsmith.Configuration.t/0` has can be set at the app level configuration.
When set at the app level you don't need to generate clients when using `Flagsmith.Client` module functions, unless you want or need different options.
## Options
- `environment_key` -> a server side sdk key (required)
- `api_url` -> the base url to which requests against the Flagsmith API will be made (defaults to: "https://api.flagsmith.com/api/v1>")
- `default_flag_handler` -> a 1 arity function that receives a feature name (String.t()) and is called when calling feature related functions and the given feature isn't found -> defaults to returning `:not_found`
- `custom_headers` -> additional headers to include in the calls to the Flagsmith API, defaults to an empty list (no additional headers)
- `request_timeout_milliseconds` -> the timeout for the HTTP adapter when doing calls to the Flagsmith API (defaults to 5_000 milliseconds)
- `enable_local_evaluation` -> starts a poller cache for each sdk key in use, on their first invocation and keeps a local auto-refreshing cache with the environment document for each. This allows you to keep Flagsmith API calls to a minimum as the environment can be fetched locally and used for any other related functionality in the client.
- `environment_refresh_interval_milliseconds` -> the time to wait between polling the Flagsmith API for a new environment document, only relevant if `enable_local_evaluation` is set to true.
- `retries` -> the number of times the http adapter is allowed to retry failed calls to the Flagsmith API before deeming the response failed. Keep in mind that with local_evaluation and analytics, even if the requests fail after whatever number of retries you set here, they will keep being retried as their time-cycle resets (for the poller whatever is the environment_refresh_interval_milliseconds, for the analytics they're batched, and a dump is tried every 1 minute)
- `enable_analytics` -> track feature queries by reporting automatically to the Flagsmith API analytics endpoint queries and lookups to features. This only works when using the `Flagsmith.Client` module functions such as `is_feature_enabled`, `get_feature_value` and `get_flag`.
To use the client library without application level configuration (or to override it) whenever a configuration is expected you can pass either a `t:Flagsmith.Configuration.t/0` struct or a keyword list with the options as elements. For instance:
```elixir
{:ok, environment} = Flagsmith.Client.get_environment(environment_key: "MY_SDK_KEY", enable_local_evaluation: true)
```
Or by passing a `t:Flagsmith.Configuration.t/0` to it:
```elixir
config = Flagsmith.Client.new(environment_key: "MY_SDK_KEY", enable_analytics: true, api_url: "https://my-own-api-endpoint.com")
{:ok, environment} = Flagsmith.Client.get_environment(config)
```
If you configured the `Flagsmith.Client` at the application level, with at least an `:environment_key`, you can simply call:
```elixir
{:ok, environment} = Flagsmith.Client.get_environment()
```
The precedence for the configuration values is `Options > Application config > Defaults`.
To enable analytics or local evaluation, besides setting the configuration keys `enable_local_evaluation` and/or `enable_analytics`, you need to make sure `Flagsmith.Supervisor` is started before calling the client module, usually by placing it in your application supervision tree:
```elixir
defmodule YourAppWeb.Application do
# ...
def start(_type, _args) do
children = [
Flagsmith.Supervisor,
# ... other stuff
]
opts = [strategy: :one_for_one, name: YourAppWeb.Supervisor]
Supervisor.start_link(children, opts)
end
# ...
```
If you only use API evaluation without tracking any analytics you don't need to to start the supervisor.