Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/horvathandris/openfeature-gleam-sdk
Gleam implementation of the OpenFeature SDK
https://github.com/horvathandris/openfeature-gleam-sdk
gleam openfeature sdk
Last synced: 7 days ago
JSON representation
Gleam implementation of the OpenFeature SDK
- Host: GitHub
- URL: https://github.com/horvathandris/openfeature-gleam-sdk
- Owner: horvathandris
- License: apache-2.0
- Created: 2024-07-02T08:27:08.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2024-09-10T07:58:41.000Z (4 months ago)
- Last Synced: 2024-12-31T22:33:15.155Z (11 days ago)
- Topics: gleam, openfeature, sdk
- Language: Gleam
- Homepage:
- Size: 87.9 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-gleam - openfeature - [📚](https://hexdocs.pm/openfeature/) - The Gleam SDK for the OpenFeature specification. (Packages / SDKs)
README
# OpenFeature Gleam SDK
[![Package Version](https://img.shields.io/hexpm/v/openfeature)](https://hex.pm/packages/openfeature)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/openfeature/)[OpenFeature](https://openfeature.dev) is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool.
This repository contains the unofficial SDK implementation of the [specification](https://openfeature.dev/specification/) for the [Gleam](https://gleam.run/) programming language.
## 🚀 Quick start
### Requirements
- Gleam [1+](https://github.com/gleam-lang/gleam/releases/tag/v1.0.0)
### Install
```sh
gleam add openfeature
```### Usage
```gleam
import gleam/bool
import gleam/dict
import gleam/dynamic
import gleam/io
import gleam/option.{None}
import openfeature
import openfeature/client
import openfeature/evaluation_context
import openfeature/providers/in_memorypub fn main() {
// flags defined in memory
let v2_flag =
in_memory.Flag(
default_variant: "off",
variants: dict.from_list([
#("off", dynamic.from(False)),
#("on", dynamic.from(True)),
]),
context_evaluator: None,
)
let flags = dict.from_list([#("v2_enabled", v2_flag)])// configure a provider
let _ = openfeature.set_provider(in_memory.provider(flags))// get a bool flag value
let flag_value =
openfeature.get_client()
|> client.get_bool_value("v2_enabled", False, evaluation_context.empty())// use the returned flag value
io.println("`v2_enabled` evaluated to: " <> bool.to_string(flag_value))
}
```Further documentation can be found at .
## 🌟 Features
| Status | Features | Description |
| ------ | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| ✅ | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. |
| ✅ | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). |
| ❌ | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. |
| ❌ | [Logging](#logging) | Integrate with popular logging packages. |
| ✅ | [Domains](#domains) | Logically bind clients with providers. |
| ❌ | [Eventing](#eventing) | React to state changes in the provider or flag management system. |
| ✅ | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
| ⚠️ | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. |Implemented: ✅ | In-progress: ⚠️ | Not implemented yet: ❌
### Providers
[Providers](https://openfeature.dev/docs/reference/concepts/provider) are an abstraction between a flag management system and the OpenFeature SDK. Look [here](https://openfeature.dev/ecosystem?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Provider&instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=Gleam) for a complete list of available providers. If the provider you're looking for hasn't been created yet, see the [develop a provider](#develop-a-provider) section to learn how to build it yourself.
Once you've added a provider as a dependency, it can be registered with OpenFeature like this:
```gleam
import openfeatureopenfeature.set_provider(my_provider())
```In some situations, it may be beneficial to register multiple providers in the same application. This is possible using [domains](#domains), which is covered in more details below.
### Targeting
Sometimes, the value of a flag must consider some dynamic criteria about the application or user, such as the user's location, IP, email address, or the server's location. In OpenFeature, we refer to this as [targeting](https://openfeature.dev/specification/glossary#targeting). If the flag management system you're using supports targeting, you can provide the input data using the [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context).
```gleam
import gleam/dynamic
import gleam/option.{None}
import openfeature
import openfeature/client
import openfeature/evaluation_context.{EvaluationContext}// set the global evaluation context
openfeature.set_context(
evaluation_context.targetless([
#("region", dynamic.from("us-east-1-iah-1a")),
])
)// set the client evaluation context
let my_app_client =
openfeature.get_domain_client("my-app")
|> client.set_context(
evaluation_context.targetless([
#("version", dynamic.from("1.4.6")),
])
)// set the invocation context
client.get_bool_details(
my_app_client,
"bool-flag",
False,
evaluation_context.targeted(
"userId:1234",
[#("company", dynamic.from("Wise"))]
),
)
```### Hooks
TODO
### Logging
TODO
### Domains
Clients can be assigned to a domain. A domain is a logical identifier which can be used to associate clients with a particular provider. If a domain has no associated provider, the default provider is used.
```gleam
import openfeature// registering the default provider
openfeature.set_provider(local_provider())
// registering a domain provider
openfeature.set_domain_provider("cached-domain", cached_provider())// a client bound to the default provider
openfeature.get_client()
// a client bound to the cached provider
openfeature.get_domain_client("cached-domain")
```### Eventing
TODO
### Shutdown
The OpenFeature API provides a close function to perform a cleanup of all registered providers. This should only be called when your application is in the process of shutting down.
```gleam
import openfeatureopenfeature.shutdown()
```## Extending
### Develop a provider
To develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency. This can be a new repository ~~or included in the existing contrib repository available under the OpenFeature organization~~. You’ll then need to write the provider by exporting a function that returns a value of type `FeatureProvider`, exported by the OpenFeature SDK.
```gleam
import gleam/dynamic.{type Dynamic}
import openfeature/evaluation_context.{type EvaluationContext}
import openfeature/provider.{type FeatureProvider, FeatureProvider}pub fn my_provider() -> FeatureProvider {
FeatureProvider(
get_metadata: fn() { provider.Metadata("My Provider") },
initialize: fn(evaluation_context: EvaluationContext) {
// code to initialize your provider
todo
},
shutdown: fn() {
// code to shutdown your provider
todo
},
resolve_bool_evaluation: fn(
flag: String,
default_value: Bool,
evaluation_context: EvaluationContext,
) {
// code to evaluate a boolean value
todo
},
resolve_string_evaluation: fn(
flag: String,
default_value: String,
evaluation_context: EvaluationContext,
) {
// code to evaluate a string value
todo
},
resolve_int_evaluation: fn(
flag: String,
default_value: Int,
evaluation_context: EvaluationContext,
) {
// code to evaluate an integer value
todo
},
resolve_float_evaluation: fn(
flag: String,
default_value: Float,
evaluation_context: EvaluationContext,
) {
// code to evaluate a float value
todo
},
resolve_dynamic_evaluation: fn(
flag: String,
default_value: Dynamic,
evaluation_context: EvaluationContext,
) {
// code to evaluate a dynamic value
todo
},
)
}
```### Develop a hook
TODO