Handy tool to deal with feature toggles.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Godeps
api
engine
sample
.travis.yml
AUTHORS
CONTRIBUTORS
LICENSE
Makefile
README.md
features.go
features_test.go
go.mk

README.md

Build Status Coverage Status

Features

Features helps you to determine whether or not a feature should be made available to one or more users. You can choose one of the following ways:

  • Enable a feature only for a specific set of users;
  • Enable or disabled for a percentage of users;
  • Disable a feature.

Also known as: feature switch, feature flag, feature toggle, ...

Storage

  • Features is completely storage agnostic. You should be able to use your own storage, you just need to implement the Engine interface.
  • This library comes with an in memory store, but it's basically used for testing. You should not use this in production.

SDKs

  • Javascript (in progress)
  • Ruby (soon)
  • Python (soon)

How it works

Create an instance of Features type passing the storage as an argument:

Features := features.New(memory.New())

Create an instance of Feature type with the desired parameters and save it:

feature := engine.FeatureFlag{
  Key:     "Feature X",
  Enabled: false,
  Users:   []*engine.User{&engine.User{Id: "alice@example.org"}},
  Percentage: 10,
}
Features.Save(feature)

Check if a feature is enabled:

Features.IsEnabled("Feature X")

Check if a feature is disabled:

Features.IsDisabled("Feature X")

Execute an anonymous function if the feature is enabled:

Features.With("Feature X", func() {
  fmt.Println("`Feature X` is enabled!")
})

Execute an anonymous function if the feature is disabled:

Features.Without("Feature X", func() {
  fmt.Println("`Feature X` is disabled!")
})

Check if a feature is active for a particular user:

Features.UserHasAccess("Feature X", "alice@example.org")

User percentages

If you're rolling out a feature, you might want to enable it for a percentage of your users. There are two ways you can achieve that: Either enabling the feature for a percentage of users or disabling that.

  • Enable the feature for a percentage of users:
feature := engine.FeatureFlag{
  Key:     "Feature X",
  Enabled: true,
  Percentage: 10,
}
  • Disable the feature for a percentage of users:
feature := engine.FeatureFlag{
  Key:     "Feature X",
  Enabled: false,
  Percentage: 10,
}

Specific users

You might want to enable a feature for a set of users to try out and give feedback on before it's rolled out for everyone. To achieve this, you need to specify the users by doing the following:

feature := engine.FeatureFlag{
  Key:     "Feature X",
  Enabled: true,
  Users:   []*engine.User{&engine.User{Id: "alice@example.org"}},
}

HTTP API

Features comes with an HTTP API that's used by the SDKs, but you should not expose that to the world because there's no authentication layer.

API endpoints

Create a new feature flag

curl -i http://localhost:8000/features -XPOST -d '{"key": "login-via-email", "percentage": 90, "enabled": true, "users": [{"id": "alice@example.org"}]}'

Response:

HTTP/1.1 201 Created
Content-Type: application/json
Date: Tue, 03 Nov 2015 23:21:07 GMT
Content-Length: 94

{"enabled":true,"key":"login-via-email","users":[{"id":"alice@example.org"}],"percentage":90}

Update an existing feature flag

curl -i http://localhost:8000/features/login-via-email -XPUT -d '{"key": "login-via-email", "percentage": 90, "enabled": false, "users": [{"id": "bob@example.org"}]}'

Response:

HTTP/1.1 200 OK
Content-Type: application/json
Date: Tue, 03 Nov 2015 23:22:05 GMT
Content-Length: 93

{"enabled":false,"key":"login-via-email","users":[{"id":"bob@example.org"}],"percentage":90}

Delete an existing feature flag

curl -i http://localhost:8000/features/login-via-email -XDELETE

Response:

HTTP/1.1 204 No Content
Content-Type: application/json
Date: Tue, 03 Nov 2015 23:24:46 GMT

Get an existing feature flag

curl -i http://localhost:8000/features/login-via-email

Response:

HTTP/1.1 200 OK
Content-Type: application/json
Date: Tue, 03 Nov 2015 23:26:22 GMT
Content-Length: 94

{"enabled":true,"key":"login-via-email","users":[{"id":"alice@example.org"}],"percentage":90}

List all feature flags

curl -i http://localhost:8000/features

Response:

{
  "items": [
    {
      "percentage": 90,
      "enabled": true,
      "users": [
        {
          "id": "alice@example.org"
        }
      ],
      "key": "login-via-email"
    }
  ],
  "item_count": 1
}

Validate access

curl -i http://localhost:8000/features -XPUT -d '{"key": "login-via-email", "user": "alice@example.org"}'

Response for success:

HTTP/1.1 200 OK
Content-Type: application/json
Date: Wed, 04 Nov 2015 00:19:46 GMT
Content-Length: 0

Response for failure:

HTTP/1.1 403 Forbidden
Content-Type: application/json
Date: Wed, 04 Nov 2015 00:20:51 GMT
Content-Length: 0