nryanov / feature4s

feature4s is a small library which implement the Feature Toggles pattern for scala.

Version Matrix

feature4s

GitHub license Maven Central Codecov feature4s CI

feature4s is a small library which implement the Feature Toggles pattern for scala.

Get started

libraryDependencies ++= Seq(
  "com.nryanov.feature4s" %% "<feature4s-backend>" % "[version]" 
)
import feature4s.redis.lettuce._
import io.lettuce.core.RedisClient

object Application {
  def main(args: Array[String]): Unit = {
    val client = RedisClient.create(s"redis://localhost:6379")
    val namespace = "features"
    val featureRegistry = LettuceSyncFeatureRegistry.useConnection(client.connect(), namespace)
   
    val myFeature = featureRegistry.register("featureName", enable = false, Some("description"))
   
    if (myFeature.isEnable()) {
      // if feature is enable logic
    } else {
      // if feature is disable logic    
    } 
    
    client.close()
  }
}

OpenAPI documentation

API for feature4s is build using tapir. Choose a preferred backend and json-lib and then add the following dependencies:

libraryDependencies ++= Seq(
  "com.nryanov.feature4s" %% "<feature4s-tapir-backend>" % "[version]"
  "com.nryanov.feature4s" %% "<feature4s-tapir-json>" % "[version]" 
)

Supported http servers

For more information about using these servers with tapir see: doc

Supported json integrations

Json codecs for internal feature4s structures can be added like this:

import features.tapir.json.[circe/json4s/sprayjson/tethys]._

For json4s you also need to choose serialization backend: native or jackson.

libraryDependencies ++= Seq(
  "org.json4s" %% "json4s-native" % "{latestVersion}"
// or
  "org.json4s" %% "json4s-jackson" % "{latestVersion}" 
)

After that just add a format:

implicit val formats: Formats = Serialization.formats(NoTypeHints)

Examples

Hello world examples with OpenAPI docs can be found in the examples folder.

Backends

Backend Client
Aerospike aerospike-client-java
Redis jedis
lettuce
redisson
Zookeeper curator

Implementations

Class Effect
InMemoryIdFeatureRegistry None (Identity)
InMemoryCatsFeatureRegistry F[_]: cats.effect.Concurrent
InMemoryZioFeatureRegistry zio.Task
CachedFeatureRegistry F[_] (wrapper for any FeatureRegistry[F[_]])
AerospikeSyncFeatureRegistry None (Identity)
AerospikeCatsFeatureRegistry F[_]: cats.effect.Sync: cats.effect.ContextShift
AerospikeZioFeatureRegistry zio.Task
JedisClusterSyncFeatureRegistry None (Identity)
JedisClusterCatsFeatureRegistry F[_]: cats.effect.Sync: cats.effect.ContextShift
JedisClusterZioFeatureRegistry zio.Task
JedisSyncFeatureRegistry (JedisPool && JedisSentinel) None (Identity)
JedisCatsFeatureRegistry (JedisPool && JedisSentinel) F[_]: cats.effect.Sync: cats.effect.ContextShift
JedisZioFeatureRegistry (JedisPool && JedisSentinel) zio.Task
LettuceSyncFeatureRegistry None (Identity)
LettuceAsyncFeatureRegistry scala.concurrent.Future
LettuceCatsFeatureRegistry F[_]: cats.effect.Sync: cats.effect.ContextShift
LettuceCatsAsyncFeatureRegistry F[_]: cats.effect.Concurrent
LettuceZioFeatureRegistry zio.Task
LettuceZioAsyncFeatureRegistry zio.Task
RedissonSyncFeatureRegistry None (Identity)
RedissonAsyncFeatureRegistry scala.concurrent.Future
RedissonCatsFeatureRegistry F[_]: cats.effect.Sync: cats.effect.ContextShift
RedissonCatsAsyncFeatureRegistry F[_]: cats.effect.Concurrent
RedissonZioFeatureRegistry zio.Task
RedissonZioAsyncFeatureRegistry zio.Task
ZookeeperSyncFeatureRegistry None (Identity)
ZookeeperCatsFeatureRegistry F[_]: cats.effect.Sync: cats.effect.ContextShift
ZookeeperZioFeatureRegistry zio.Task