go-feature-flag alternatives and similar packages
Based on the "Server Applications" category.
Alternatively, view go-feature-flag alternatives based on common mentions on social networks and blogs.
-
etcd
Distributed reliable key-value store for the most critical data of a distributed system -
Caddy
Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS -
Vault
A tool for secrets management, encryption as a service, and privileged access management -
consul
Consul is a distributed, highly available, and data center aware solution to connect and configure applications across dynamic, distributed infrastructure. -
apex
Build, deploy, and manage AWS Lambda functions with ease (with Go support!). -
RoadRunner
🤯 High-performance PHP application server, process manager written in Go and powered with plugins -
Ponzu
Headless CMS with automatic JSON API. Featuring auto-HTTPS from Let's Encrypt, HTTP/2 Server Push, and flexible server framework written in Go. -
SFTPGo
Fully featured and highly configurable SFTP server with optional HTTP/S, FTP/S and WebDAV support - S3, Google Cloud Storage, Azure Blob -
Jocko
Kafka implemented in Golang with built-in coordination (No ZK dep, single binary install, Cloud Native) -
discovery
A registry for resilient mid-tier load balancing and failover. -
Flagr
Flagr is a feature flagging, A/B testing and dynamic configuration microservice -
algernon
:tophat: Small self-contained pure-Go web server with Lua, Markdown, HTTP/2, QUIC, Redis and PostgreSQL support -
Trickster
Open Source HTTP Reverse Proxy Cache and Time Series Dashboard Accelerator -
Key Transparency
A transparent and secure way to look up public keys. -
Rendora
dynamic server-side rendering using headless Chrome to effortlessly solve the SEO problem for modern javascript websites -
jackal
💬 Instant messaging server for the Extensible Messaging and Presence Protocol (XMPP). -
Golang API Starter Kit
Go Server/API boilerplate using best practices DDD CQRS ES gRPC -
Euterpe
Self-hosted music streaming server 🎶 with RESTful API and Web interface. Think of it as your very own Spotify! ☁️🎧 -
Walrus
🔥 Fast, Secure and Reliable System Backup, Set up in Minutes. -
goproxy
🦁 goproxy is a proxy server which can forward http or https requests to remote servers./ goproxy 是一个反向代理服务器,支持转发 http/https 请求。 -
Eru
Eru, a simple, stateless, flexible, production-ready orchestrator designed to easily integrate into existing workflows. Can run any virtualization things in long or short time. -
marathon-consul
Integrates Marathon apps with Consul service discovery. -
cortex-tenant
Prometheus remote write proxy that adds Cortex tenant ID based on metric labels -
go-proxy-cache
Simple Reverse Proxy with Caching, written in Go, using Redis. -
lets-proxy2
Reverse proxy with automatically obtains TLS certificates from Let's Encrypt -
Simple CRUD App w/ Gorilla/Mux, MariaDB
Simple CRUD Application with Go, Gorilla/mux, MariaDB, Redis. -
psql-streamer
Stream database events from PostgreSQL to Kafka -
nginx-prometheus
Turn Nginx logs into Prometheus metrics -
simple-jwt-provider
Simple and lightweight provider which exhibits JWTs, supports login, password-reset (via mail) and user management. -
autobd
autobd is an automated, networked and containerized backup solution -
protoxy
A proxy server than converts JSON request bodies to protocol buffers -
go-fitbit
Fitbit API for Go to fetch, add, update and delete data on Fitbit using REST API -
riemann-relay
Service for relaying Riemann events to Riemann/Carbon destinations
Access the most powerful time series database as a service
Do you think we are missing an alternative of go-feature-flag or a related project?
README
go-feature-flag v1 feedback
go-feature-flag is heading towards v1 and it may require a change on how to design your flags (no worries we will keep backward compatibility).
The roadmap is now publicly available in this issue #291, feel free to comment and give any feedback.
🎛️ go-feature-flag 
Feature flags with no complex system to maintain!
Installation
go get github.com/thomaspoignant/go-feature-flag
What is go-feature-flag?
A simple and complete feature flag solution, without any complex backend system to install, all you need is a file as your backend.
No server is needed, just add a file to your central system and all your services will react to the changes in this file.
go-feature-flags supports:
- Storing your configuration flags file on various locations (
HTTP
,S3
,GitHub
,file
,Google Cloud Storage
,Kubernetes
...). - Configuring your flags in various format (
JSON
,TOML
andYAML
). - Adding complex rules to target your users.
- Use complex rollout strategy for your flags :
- Run A/B testing experimentation.
- Progressively rollout a feature.
- Schedule your flag updates.
- Exporting your flags usage data (
S3
,log
,file
,Google Cloud Storage
...). - Getting notified when a flag has been changed (
webhook
andslack
).
If you are not familiar with feature flags, also called feature Toggles, you can read this article from Martin Fowler where he explains why this is a great pattern.
I've also written an article explaining why feature flags can fasten your iteration cycle.
The code of this demo is available in thomaspoignant/go-feature-flag-demo
repository.
Can I use GO Feature Flag with another language?
Originally GO Feature Flag was built to be a GOlang only library, but it limits the ecsystem too much.
To be compatible with more language we have implemented the GO Feature Flag Relay Proxy.
It is a service you can host that provides an API to evaluate your flags, you can call it using HTTP to get your variation.
Since we believe in standardization we are also implementing Open-feature providers to interact with this API in the language of your choice.
(Open-feature is still at an early stage, so not all languages are supported and expect some changes in the future)
Getting started
First, you need to initialize the ffclient
with the location of your backend file.
err := ffclient.Init(ffclient.Config{
PollingInterval: 3 * time.Second,
Retriever: &httpretriever.Retriever{
URL: "http://example.com/flag-config.yaml",
},
})
defer ffclient.Close()
This example will load a file from an HTTP endpoint and will refresh the flags every 3 seconds (if you omit the PollingInterval, the default value is 60 seconds).
Now you can evaluate your flags anywhere in your code.
user := ffuser.NewUser("user-unique-key")
hasFlag, _ := ffclient.BoolVariation("test-flag", user, false)
if hasFlag {
// flag "test-flag" is true for the user
} else {
// flag "test-flag" is false for the user
}
The full documentation is available on https://docs.gofeatureflag.org
You can find more examples in the examples/ directory.
Configuration
go-feature-flag
needs to be initialized to be used.
During the initialization you must give a ffclient.Config{}
configuration object.
ffclient.Config{}
is the only location where you can put the configuration.
Example
ffclient.Init(ffclient.Config{
PollingInterval: 3 * time.Second,
Logger: log.New(file, "/tmp/log", 0),
Context: context.Background(),
Retriever: &fileretriever.Retriever{Path: "testdata/flag-config.yaml"},
FileFormat: "yaml",
Notifiers: []notifier.Notifier{
&webhooknotifier.Notifier{
EndpointURL: " https://example.com/hook",
Secret: "Secret",
Meta: map[string]string{
"app.name": "my app",
},
},
},
DataExporter: ffclient.DataExporter{
FlushInterval: 10 * time.Second,
MaxEventInMemory: 1000,
Exporter: &fileexporter.Exporter{
OutputDir: "/output-data/",
},
},
StartWithRetrieverError: false,
Environment: os.Getenv("MYAPP_ENV"),
})
Configuration fields
All the configuration fields are described in the configuration documentation page.
Multiple configuration flag files
go-feature-flag
comes ready to use out of the box by calling the Init
function and it will be available everywhere.
Since most applications will want to use a single central flag configuration, the package provides this. It is similar to a singleton.
In all the examples above, they demonstrate using go-feature-flag
in its singleton style approach.
You can also create many go-feature-flag
clients to use in your application.
See the documentation for more details.
Where do I store my flags file?
The module supports different ways of retrieving the flag file.
Available retriever are:
- From GitHub
- From an HTTP endpoint
- From a S3 Bucket
- From a file
- From Google Cloud Storage
- From Kubernetes ConfigMaps
You can also create your own retriever.
Flags file format
go-feature-flag
core feature is to centralize all your feature flags in a single file, and to avoid hosting and maintaining a backend server to manage them.
Your file should be a YAML
, JSON
or TOML
file with a list of flags (examples: [YAML
](testdata/flag-config.yaml), [JSON
](testdata/flag-config.json), [TOML
](testdata/flag-config.toml)).
The easiest way to create your configuration file is to used GO Feature Flag Editor available at https://editor.gofeatureflag.org.
If you prefer to do it manually please follow instruction bellow.
A flag configuration looks like:
YAML
test-flag:
percentage: 100
rule: key eq "random-key"
true: true
false: false
default: false
disable: false
trackEvents: true
version: 1
rollout:
experimentation:
start: 2021-03-20T00:00:00.10-05:00
end: 2021-03-21T00:00:00.10-05:00
test-flag2:
rule: key eq "not-a-key"
percentage: 100
true: true
false: false
default: false
version: 12
JSON
{
"test-flag": {
"percentage": 100,
"rule": "key eq \"random-key\"",
"true": true,
"false": false,
"default": false,
"disable": false,
"trackEvents": true,
"version": 1,
"rollout": {
"experimentation": {
"start": "2021-03-20T05:00:00.100Z",
"end": "2021-03-21T05:00:00.100Z"
}
}
},
"test-flag2": {
"rule": "key eq \"not-a-key\"",
"percentage": 100,
"true": true,
"false": false,
"default": false,
"version": 12
}
}
TOML
[test-flag]
percentage = 100.0
rule = "key eq \"random-key\""
true = true
false = false
default = false
disable = false
trackEvents = true
version = 1.0
[test-flag.rollout]
[test-flag.rollout.experimentation]
start = 2021-03-20T05:00:00.100Z
end = 2021-03-21T05:00:00.100Z
[test-flag2]
rule = "key eq \"not-a-key\""
percentage = 100.0
true = true
false = false
default = false
version = 12.0
All the fields to create a flag are described in the documentation.
Rule format
The rule format is based on the nikunjy/rules
library.
All the operations can be written capitalized or lowercase (ex: eq
or EQ
can be used).
Logical Operations supported are AND
OR
.
Compare Expression and their definitions (a|b
means you can use either one of the two a
or b
):
eq|==: equals to
ne|!=: not equals to
lt|<: less than
gt|>: greater than
le|<=: less than equal to
ge|>=: greater than equal to
co: contains
sw: starts with
ew: ends with
in: in a list
pr: present
not: not of a logical expression
Examples
- Select a specific user:
key eq "[email protected]"
- Select all identified users:
anonymous ne true
- Select a user with a custom property:
userId eq "12345"
Users
Feature flag targeting and rollouts are all determined by the user you pass to your Variation calls.
The SDK defines a User
struct and a UserBuilder
to make this easy.
Here's an example:
// User with only a key
user1 := ffuser.NewUser("user1-key")
// User with a key plus other attributes
user2 = ffuser.NewUserBuilder("user2-key").
AddCustom("firstname", "John").
AddCustom("lastname", "Doe").
AddCustom("email", "[email protected]").
Build()
The most common attribute is the user's key and this is the only mandatory user attribute.
The key should also uniquely identify each user. You can use a primary key, an e-mail address, or a hash, as long as the same user always has the same key.
We recommend using a hash if possible.
All the other attributes are optional.
ℹ️ Custom attributes are one of the most powerful features. They let you have rules on these attributes and target users according to any data that you want.
You can also distinguish logged-in users from anonymous users in the SDK (check documentation about anonymous users).
Variation
The Variation methods determine whether a flag is enabled or not for a specific user.
There is a Variation method for each type:
BoolVariation
, IntVariation
, Float64Variation
, StringVariation
, JSONArrayVariation
, JSONVariation
```go linenums="1" result, _ := ffclient.BoolVariation("your.feature.key", user, false)
// result is now true or false depending on the setting of // this boolean feature flag
Variation methods take the feature **flag key**, a **user**, and a **default value**.
The default value is return when an error is encountered _(`ffclient` not initialized, variation with wrong type, flag does not exist ...)._
In the example, if the flag `your.feature.key` does not exists, result will be `false`.
Not that you will always have a usable value in the result.
## Get all flags for a specific user
If you want to send the information about a specific user to a front-end, you will want a snapshot of all the flags for
this user at a specific time.
The method `ffclient.AllFlagsState` returns a snapshot of flag values and metadata.
The function is evaluating all available flags for the user and return a `flagstate.AllFlagsState` object containing the
information you need.
The `MarshalJSON()` function will return a JSON Object, that can be directly used by your front-end application.
[More details in the documentation.](https://docs.gofeatureflag.org/docs/users#get-all-flags-for-a-specific-user)
## Rollout
A critical part of every new feature release is orchestrating the actual launch schedule between Product, Engineering, and Marketing teams.
Delivering powerful user experiences typically requires software teams to manage complex releases and make manual updates at inconvenient times.
But it doesn’t have to, having a complex **rollout** strategy allows you to have lifecycle for your flags.
### Complex rollout strategy available
- [Canary releases](https://docs.gofeatureflag.org/docs/rollout/canary) - impact randomly a subset of your users.
- [Progressive rollout](https://docs.gofeatureflag.org/docs/rollout/progressive) - increase the percentage of your flag over time.
- [Scheduled rollout](https://docs.gofeatureflag.org/docs/rollout/scheduled) - update your flag over time.
- [Experimentation rollout](https://docs.gofeatureflag.org/docs/rollout/experimentation) - serve your feature only for a determined time *(perfect for A/B testing)*.
## Notifiers
If you want to be informed when a flag has changed, you can configure a [**notifier**](https://pkg.go.dev/github.com/thomaspoignant/go-feature-flag#NotifierConfig).
A notifier will send one notification to the targeted system to inform them that a new flag configuration has been loaded.
ℹ️ `go-feature-flag` can handle more than one notifier at a time.
Available notifiers are:
- [Slack](https://docs.gofeatureflag.org/docs/notifier/slack) - Get a slack message with the changes.
- [Webhook](https://docs.gofeatureflag.org/docs/notifier/webhook) - Call an API with the changes.
## Export data
If you want to export data about how your flag are used, you can use the **`DataExporter`**.
It collects all the variations events and can save these events on several locations:
- [File](https://docs.gofeatureflag.org/docs/data_collection/file) *- create local files with the variation usages.*
- [Log](https://docs.gofeatureflag.org/docs/data_collection/log) *- use your logger to write the variation usages.*
- [S3](https://docs.gofeatureflag.org/docs/data_collection/s3) *- export your variation usages to S3.*
- [Google Cloud Storage](https://docs.gofeatureflag.org/docs/data_collection/google_cloud_storage) *- export your variation usages to Google Cloud Storage.*
- [Webhook](https://docs.gofeatureflag.org/docs/data_collection/webhook) *- export your variation usages by calling a webhook.*
Currently, we are supporting only feature events.
It represents individual flag evaluations and are considered "full fidelity" events.
**An example feature event below:**
```json
{
"kind": "feature",
"contextKind": "anonymousUser",
"userKey": "ABCD",
"creationDate": 1618228297,
"key": "test-flag",
"variation": "Default",
"value": false,
"default": false
}
The format of the data is described in the documentation.
Events are collected and send in bulk to avoid spamming your exporter (see details in how to configure data export).
How to configure data export?
In your ffclient.Config
add the DataExporter
field and configure your export location.
To avoid spamming your location everytime you have a variation called, go-feature-flag
is storing in memory all the events and send them in bulk to the exporter.
You can decide the threshold on when to send the data with the properties FlushInterval
and MaxEventInMemory
. The first threshold hit will export the data.
If there are some flags you don't want to export, you can use trackEvents
fields on these specific flags to disable the data export (see flag file format).
Example
```go linenums="1" ffclient.Config{ // ... DataExporter: ffclient.DataExporter{ FlushInterval: 10 * time.Second, MaxEventInMemory: 1000, Exporter: &fileexporter.Exporter{ OutputDir: "/output-data/", }, }, // ... }
The full configuration is [described in the documentation](https://docs.gofeatureflag.org/docs/data_collection#how-to-configure-data-export).
# How can I contribute?
This project is open for contribution, see the [contributor's guide](CONTRIBUTING.md) for some helpful tips.
## Contributors
Thanks so much to our contributors.
<a href="https://github.com/thomaspoignant/go-feature-flag/graphs/contributors">
<img src="https://contrib.rocks/image?repo=thomaspoignant/go-feature-flag" />
</a>
*Note that all licence references and agreements mentioned in the go-feature-flag README section above
are relevant to that project's source code only.