### Configure http4s API Source: https://github.com/nigozi/flag4s/blob/master/README.md Setup the flag service for http4s. ```sbt libraryDependencies += "io.nigo" %% "flag4s-api-http4s" % "0.1.5" ``` ```scala import flag4s.api.Http4sFlagApi implicit val store = RedisStore("localhost", 6379) BlazeBuilder[IO] .bindHttp(8080) .withWebSockets(true) .mountService(Http4sFlagApi.service(), "/") .serve ``` -------------------------------- ### Configure akka-http API Source: https://github.com/nigozi/flag4s/blob/master/README.md Setup the flag service for akka-http. ```sbt libraryDependencies += "io.nigo" %% "flag4s-api-akka-http" % "0.1.5" ``` ```scala import flag4s.api.AkkaFlagApi implicit val store = RedisStore("localhost", 6379) Http().bindAndHandle(AkkaFlagApi.route(), "localhost", 8080) ``` -------------------------------- ### Create HTTP Routes with Http4sFlagApi Source: https://context7.com/nigozi/flag4s/llms.txt Generate http4s routes for managing feature flags via a REST API. This example shows basic setup and usage. ```scala import flag4s.api.Http4sFlagApi import flag4s.core.store.RedisStore import cats.effect.{ExitCode, IO, IOApp} import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.implicits._ import scala.concurrent.ExecutionContext.global object FlagServer extends IOApp { implicit val store: RedisStore = RedisStore("localhost", 6379)(global) override def run(args: List[String]): IO[ExitCode] = { BlazeServerBuilder[IO](global) .bindHttp(8080, "0.0.0.0") .withHttpApp(Http4sFlagApi.service().orNotFound) .serve .compile .drain .as(ExitCode.Success) } } // Custom base path val customRoutes = Http4sFlagApi.service("feature-flags") // Endpoints will be available at /feature-flags/* ``` -------------------------------- ### HTTP API endpoints Source: https://github.com/nigozi/flag4s/blob/master/README.md Examples of interacting with the flag service via HTTP. ```http http PUT localhost:8080/flags key=featureA value=on http PUT localhost:8080/flags key=featureB value:=true ``` ```http http localhost:8080/flags/featureA ``` ```http http localhost:8080/flags ``` ```http http POST localhost:8080/flags/featureB/enable ``` ```http http POST localhost:8080/flags/featureB/disable ``` ```http http DELETE localhost:8080/flags/featureA ``` -------------------------------- ### Get Flag Source: https://context7.com/nigozi/flag4s/llms.txt Retrieve a single flag by its key or retrieve all flags. ```APIDOC ## GET /flags ### Description Retrieves a single flag by its key or all flags if no key is specified. ### Method GET ### Endpoint /flags /flags/{key} ### Parameters #### Path Parameters - **key** (string) - Optional - The key of the flag to retrieve. ### Response #### Success Response (200) - **flag** (object) - If a key is provided, returns the flag object with key and value. - **flags** (array) - If no key is provided, returns an array of all flag objects. ### Response Example ```json { "key": "featureA", "value": "on" } ``` ### Response Example (All Flags) ```json [ { "key": "featureA", "value": "on" }, { "key": "featureB", "value": true } ] ``` ``` -------------------------------- ### Extract Typed Value with get Source: https://context7.com/nigozi/flag4s/llms.txt The `get` function extracts and decodes a flag's value to a specified type. It requires the flag to be fetched first and handles potential errors during retrieval and decoding. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) val getValue: IO[Unit] = for { flagResult <- flag("maxConnections") value <- flagResult match { case Right(f) => get[Int](f) case Left(e) => IO.pure(Left(e)) } _ <- IO(value match { case Right(v) => println(s"Max connections: $v") case Left(e) => println(s"Error: ${e.getMessage}") }) } yield () getValue.unsafeRunSync() // Output: Max connections: 100 ``` -------------------------------- ### Flag Syntax Operations with flag4s.syntax Source: https://context7.com/nigozi/flag4s/llms.txt Utilize extension methods for idiomatic Scala flag operations, including checking enabled status, specific values, getting typed values, conditional execution, and updating flags. ```scala import flag4s.core._ import flag4s.syntax._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) val syntaxExample: IO[Unit] = for { f <- fatalFlag("myFeature") // Check if enabled (for boolean flags) isOn <- f.enabled _ <- IO(println(s"Is enabled: $isOn")) // Check if equals specific value isProduction <- f.is("production") _ <- IO(println(s"Is production: $isProduction")) // Get typed value value <- f.get[String] _ <- IO(println(s"Value: $value")) // Conditional execution if enabled _ <- f.ifEnabled { println("Feature is ON - executing code block") } // Conditional execution if value matches _ <- f.ifIs("on") { println("Feature value is 'on' - executing code block") } // Update flag value updated <- f.set("off") _ <- IO(println(s"Updated flag: $updated")) } yield () syntaxExample.unsafeRunSync() ``` -------------------------------- ### GET /is - Check Flag Value Equality Source: https://context7.com/nigozi/flag4s/llms.txt Checks if a flag's value equals the specified value. Works with any type that has a Circe Encoder. ```APIDOC ## GET /is ### Description Checks if a flag's value equals the specified value. Works with any type that has a Circe Encoder. ### Method GET ### Endpoint /is ### Parameters #### Query Parameters - **key** (string) - Required - The key of the flag to check. - **value** (any) - Required - The value to compare against. ### Response #### Success Response (200) - **isEqual** (boolean) - `true` if the flag's value matches the specified value, `false` otherwise. #### Response Example ```json true ``` ``` -------------------------------- ### GET /get - Extract Typed Value from Flag Source: https://context7.com/nigozi/flag4s/llms.txt Extracts and decodes the flag's value to the specified type. ```APIDOC ## GET /get ### Description Extracts and decodes the flag's value to the specified type. ### Method GET ### Endpoint /get ### Parameters #### Query Parameters - **key** (string) - Required - The key of the flag to retrieve. - **type** (string) - Required - The target type to decode the flag's value into (e.g., `Int`, `String`, `Boolean`). ### Response #### Success Response (200) - **value** (any) - The decoded value of the flag. #### Error Response (400 Bad Request or 422 Unprocessable Entity) - **Throwable** (object) - An error indicating a decoding failure or type mismatch. #### Response Example ```json 100 ``` ``` -------------------------------- ### GET /enabled - Check Boolean Flag Status Source: https://context7.com/nigozi/flag4s/llms.txt Checks if a boolean flag's value is `true`. ```APIDOC ## GET /enabled ### Description Checks if a boolean flag's value is `true`. ### Method GET ### Endpoint /enabled ### Parameters #### Query Parameters - **key** (string) - Required - The key of the boolean flag to check. ### Response #### Success Response (200) - **isEnabled** (boolean) - `true` if the flag is enabled, `false` otherwise. #### Response Example ```json true ``` ``` -------------------------------- ### Configure RedisStore Source: https://context7.com/nigozi/flag4s/llms.txt Instantiate RedisStore with host and port. Optionally configure database and password for authentication. ```scala import flag4s.core.store.RedisStore import scala.concurrent.ExecutionContext.Implicits.global // Basic Redis connection implicit val store: RedisStore = RedisStore("localhost", 6379) // With custom database and secret val storeWithAuth = new RedisStore( host = "localhost", port = 6379, database = 1, secret = Some("redis-password") ) ``` -------------------------------- ### Initialize Akka HTTP Server Source: https://context7.com/nigozi/flag4s/llms.txt Set up an Akka HTTP server with flag4s routes and optional custom base paths. ```scala import flag4s.api.AkkaFlagApi import flag4s.core.store.RedisStore import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import scala.concurrent.ExecutionContext.Implicits.global import scala.io.StdIn object AkkaFlagServer extends App { implicit val system: ActorSystem = ActorSystem("flag-system") implicit val materializer: ActorMaterializer = ActorMaterializer() implicit val store: RedisStore = RedisStore("localhost", 6379) val bindingFuture = Http().bindAndHandle( AkkaFlagApi.route(), "localhost", 8080 ) println("Server running at http://localhost:8080/") println("Press ENTER to stop...") StdIn.readLine() bindingFuture .flatMap(_.unbind()) .onComplete(_ => system.terminate()) } // Custom base path val customRoute = AkkaFlagApi.route("feature-flags") // Endpoints will be available at /feature-flags/* ``` -------------------------------- ### Configure ConfigStore Source: https://context7.com/nigozi/flag4s/llms.txt Initialize ConfigStore with the path to a local configuration file. This store is read-only. ```scala import flag4s.core.store.ConfigStore import scala.concurrent.ExecutionContext.Implicits.global // Create store from config file implicit val store: ConfigStore = ConfigStore("/path/to/features.conf") // Config file format (features.conf): // features { // featureA: true // featureB: "on" // featureC: "premium" // } ``` -------------------------------- ### Configure ConsulStore Source: https://context7.com/nigozi/flag4s/llms.txt Create a ConsulStore using a Resource pattern, specifying host and port. Optional parameters include basePath and ACL token. ```scala import flag4s.core.store.ConsulStore import cats.effect.{IO, Resource} import scala.concurrent.ExecutionContext.Implicits.global // Basic Consul connection using Resource pattern val consulResource: Resource[IO, ConsulStore] = ConsulStore("localhost", 8500) // With base path and ACL token val consulWithAuth: Resource[IO, ConsulStore] = ConsulStore( host = "localhost", port = 8500, basePath = "feature-flags", aclToken = Some("your-acl-token") ) // Usage with Resource consulResource.use { implicit store => for { flag <- flag("myFeature") _ <- IO(println(s"Flag value: $flag")) } yield () } ``` -------------------------------- ### Configure flag store Source: https://github.com/nigozi/flag4s/blob/master/README.md Initialize a key/value store for flag persistence. ```scala import flag4s.core.store._ implicit val store = ConsulStore("localhost", 8500) //implicit val store = RedisStore("localhost", 6379) //implicit val store = ConfigStore("path-to-config-file") ``` -------------------------------- ### Use flag syntax Source: https://github.com/nigozi/flag4s/blob/master/README.md Fluent syntax for checking and setting flags. ```scala import flag4s.core._ import flag4s.syntax._ boolFlag.enabled strFlag.is("on") dblFlag.is(1.1) boolFlag.ifEnabled { //code block } strFlag.ifIs("on") { //code block } dblFlag.ifIs(1.1) { //code block } boolFlag.set(false) strFlag.set("off") dblFlag.set(2.0) ``` -------------------------------- ### Implement Custom Store Source: https://context7.com/nigozi/flag4s/llms.txt Create a custom storage backend by implementing the Store trait. ```scala import flag4s.core.store.Store import cats.effect.IO import io.circe.{Decoder, Encoder, Json} import io.circe.syntax._ class InMemoryStore extends Store { private var flags: Map[String, Json] = Map.empty override def put[A: Encoder](key: String, value: A): IO[Either[Throwable, A]] = { flags = flags + (key -> value.asJson) IO.pure(Right(value)) } override def rawValue(key: String): IO[Either[Throwable, Json]] = IO.pure( flags.get(key) .toRight(new RuntimeException(s"key $key not found")) ) override def keys(): IO[Either[Throwable, List[String]]] = IO.pure(Right(flags.keys.toList)) override def remove(key: String): IO[Either[Throwable, Unit]] = { flags = flags - key IO.pure(Right(())) } } // Usage implicit val store: InMemoryStore = new InMemoryStore() ``` -------------------------------- ### Define ConfigStore flags Source: https://github.com/nigozi/flag4s/blob/master/README.md Format for flags when using the ConfigStore. ```hocon features { featureA: true featureB: "on" ... } ``` -------------------------------- ### HTTP Endpoint: Create/Update Flag Source: https://context7.com/nigozi/flag4s/llms.txt Demonstrates how to create or update a feature flag using a PUT request to the HTTP API. Requires a running http4s server. ```bash # Create a string flag curl -X PUT http://localhost:8080/flags \ -H "Content-Type: application/json" \ -d '{"key": "featureA", "value": "on"}' ``` -------------------------------- ### Retrieve Flags via HTTP Source: https://context7.com/nigozi/flag4s/llms.txt Fetch a specific flag by key or list all available flags. ```bash curl http://localhost:8080/flags/featureA ``` ```bash curl http://localhost:8080/flags ``` -------------------------------- ### POST /newFlag - Create a New Flag Source: https://context7.com/nigozi/flag4s/llms.txt Creates a new flag with the specified key and value. Returns `Left` if the flag already exists. ```APIDOC ## POST /newFlag ### Description Creates a new flag with the specified key and value. Returns `Left` if the flag already exists. ### Method POST ### Endpoint /newFlag ### Parameters #### Request Body - **key** (string) - Required - The unique key for the flag. - **value** (any) - Required - The value to set for the flag. Can be boolean, string, or numeric. ### Request Example ```json { "key": "darkMode", "value": true } ``` ### Response #### Success Response (200) - **Flag** (object) - The created flag object. - **key** (string) - The flag's key. - **value** (any) - The flag's value. #### Error Response (409 Conflict) - **Throwable** (object) - An error indicating the flag already exists. #### Response Example ```json { "key": "darkMode", "value": true } ``` ``` -------------------------------- ### POST /switchFlag - Create or Update a Flag Source: https://context7.com/nigozi/flag4s/llms.txt Sets the flag's value, creating the flag if it doesn't exist. Type validation is performed on existing flags. ```APIDOC ## POST /switchFlag ### Description Sets the flag's value, creating the flag if it doesn't exist. Type validation is performed on existing flags. ### Method POST ### Endpoint /switchFlag ### Parameters #### Request Body - **key** (string) - Required - The unique key for the flag. - **value** (any) - Required - The value to set for the flag. ### Request Example ```json { "key": "featureX", "value": true } ``` ### Response #### Success Response (200) - **Flag** (object) - The updated or created flag object. - **key** (string) - The flag's key. - **value** (any) - The flag's value. #### Error Response (400 Bad Request) - **Throwable** (object) - An error indicating a type mismatch if the flag exists. #### Response Example ```json { "key": "featureX", "value": true } ``` ``` -------------------------------- ### Add flag4s Dependencies Source: https://context7.com/nigozi/flag4s/llms.txt Include flag4s core, optional HTTP APIs, and cats-effect dependencies in your build.sbt file. ```scala // Core library (required) libraryDependencies += "io.nigo" %% "flag4s-core" % "0.1.5" // HTTP API for http4s (optional) libraryDependencies += "io.nigo" %% "flag4s-api-http4s" % "0.1.5" // HTTP API for Akka HTTP (optional) libraryDependencies += "io.nigo" %% "flag4s-api-akka-http" % "0.1.5" // Required cats-effect dependency libraryDependencies += "org.typelevel" %% "cats-effect" % "2.1.2" ``` -------------------------------- ### Create and set flags Source: https://github.com/nigozi/flag4s/blob/master/README.md Modify flag values or create new ones. ```scala newFlag("boolFlag", true) //creates a new flag with value true, Left if flag already exists switchFlag("boolFlag", false) //sets the flag's value to false, creates the flag if doesn't exist set(strFlag, "off") //sets the flag's value to "off", Left if flag doesn't exist ``` -------------------------------- ### Add flag4s-core dependency Source: https://github.com/nigozi/flag4s/blob/master/README.md Include the core library for feature flag management. ```sbt libraryDependencies += "io.nigo" %% "flag4s-core" % "0.1.5" ``` -------------------------------- ### Create Flags via HTTP Source: https://context7.com/nigozi/flag4s/llms.txt Use PUT requests to create or update boolean and numeric flags in the store. ```bash curl -X PUT http://localhost:8080/flags \ -H "Content-Type: application/json" \ -d '{"key": "featureB", "value": true}' ``` ```bash curl -X PUT http://localhost:8080/flags \ -H "Content-Type: application/json" \ -d '{"key": "maxRetries", "value": 5}' ``` -------------------------------- ### PUT /flags Source: https://context7.com/nigozi/flag4s/llms.txt Creates or updates a feature flag in the store. ```APIDOC ## PUT /flags ### Description Creates or updates a feature flag by providing a key and a value. ### Method PUT ### Endpoint /flags ### Request Body - **key** (string) - Required - The unique identifier for the flag. - **value** (string) - Required - The value to assign to the flag. ### Request Example { "key": "featureA", "value": "on" } ### Response #### Success Response (200) - **status** (string) - Confirmation of the update operation. ``` -------------------------------- ### Add cats-effect dependency Source: https://github.com/nigozi/flag4s/blob/master/README.md Include the required cats-effect library for IO operations. ```sbt libraryDependencies += "org.typelevel" %% "cats-effect" % "version" ``` -------------------------------- ### Manage flags with core functions Source: https://github.com/nigozi/flag4s/blob/master/README.md Perform read operations on flags using IO-based functions. ```scala import flag4s.core._ flag("featX") //returns the flag as type of Either[Throwable, Flag] fatalFlag("featX") //returns the flag or throws exception if flag doesn't exist enabled(boolFlag) //checks if the flag's value is true is(strFlag, "on") //checks if the flag's value is "on" withFlag("boolFlag", true) { //executes the code block if flag's value is true //code block } withFlag("strFlag", "on") { //executes the code block if flag's value is "on" //code block } //or ifEnabled(boolFlag) { //executes the code block if the flag's value is true //code block } ifIs(strFlag, "on") { //executes the code block if the flag's value is "on" //code block } get[Double](dblFlag) //returns the flag's value as Double ``` -------------------------------- ### Retrieve a Flag or Throw Source: https://context7.com/nigozi/flag4s/llms.txt Use `fatalFlag` to retrieve a flag, which throws an exception if the flag is not found. This is suitable for flags essential for application startup. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) // Fatal retrieval - throws if not found val requiredFlag: IO[Flag] = fatalFlag("requiredFeature") val flag = requiredFlag.unsafeRunSync() println(s"Required flag: ${flag.key} = ${flag.value}") // Throws RuntimeException if flag doesn't exist ``` -------------------------------- ### Conditional Execution with withFlag Source: https://context7.com/nigozi/flag4s/llms.txt Execute a code block if a flag matches a specific key and value. Requires a RedisStore instance. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) // Execute code if boolean flag is true val booleanCheck: IO[Either[Throwable, String]] = withFlag("betaFeatures", true) { "Beta features are enabled!" } // Execute code if string flag matches val stringCheck: IO[Either[Throwable, Int]] = withFlag("tier", "premium") { calculatePremiumPrice() } def calculatePremiumPrice(): Int = 99 booleanCheck.unsafeRunSync() match { case Right(msg) => println(msg) case Left(e) => println(s"Not enabled: ${e.getMessage}") } // Output: Beta features are enabled! // Or: Not enabled: flag betaFeatures is not true ``` -------------------------------- ### Create/Update Flag Source: https://context7.com/nigozi/flag4s/llms.txt Create or update a feature flag with a specified key and value. The value can be a boolean or a number. ```APIDOC ## PUT /flags ### Description Creates or updates a feature flag. ### Method PUT ### Endpoint /flags ### Request Body - **key** (string) - Required - The unique identifier for the flag. - **value** (boolean | number) - Required - The value of the flag. ### Request Example ```json { "key": "featureB", "value": true } ``` ### Response #### Success Response (200) - **value** (boolean | number) - The updated value of the flag. ### Response Example ```json true ``` ``` -------------------------------- ### Create New Flag with newFlag Source: https://context7.com/nigozi/flag4s/llms.txt Use `newFlag` to create a flag with a specified key and value. It returns `Left` if the flag already exists. Supports boolean, string, and numeric types. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) // Create boolean flag val boolResult: IO[Either[Throwable, Flag]] = newFlag("darkMode", true) // Create string flag val strResult: IO[Either[Throwable, Flag]] = newFlag("theme", "dark") // Create numeric flag val numResult: IO[Either[Throwable, Flag]] = newFlag("maxRetries", 3) // Execute and handle result boolResult.unsafeRunSync() match { case Right(f) => println(s"Created flag: ${f.key} = ${f.value}") case Left(e) => println(s"Failed to create: ${e.getMessage}") } // Output: Created flag: darkMode = true // If flag exists: Failed to create: flag darkMode already exists ``` -------------------------------- ### Akka HTTP Endpoint Operations Source: https://context7.com/nigozi/flag4s/llms.txt Standard flag operations available through the Akka HTTP API. ```bash curl -X PUT http://localhost:8080/flags \ -H "Content-Type: application/json" \ -d '{"key": "darkMode", "value": true}' curl http://localhost:8080/flags/darkMode curl http://localhost:8080/flags curl -X POST http://localhost:8080/flags/darkMode/enable curl -X POST http://localhost:8080/flags/darkMode/disable curl -X DELETE http://localhost:8080/flags/darkMode ``` -------------------------------- ### Retrieve a Flag Safely Source: https://context7.com/nigozi/flag4s/llms.txt Use the `flag` function to retrieve a feature flag by its key. It returns an `IO[Either[Throwable, Flag]]` for safe handling of potential errors. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) // Safe retrieval - returns Either val safeFlag: IO[Either[Throwable, Flag]] = flag("darkMode") safeFlag.unsafeRunSync() match { case Right(f) => println(s"Flag found: ${f.key} = ${f.value}") case Left(e) => println(s"Flag not found: ${e.getMessage}") } // Output: Flag found: darkMode = true ``` -------------------------------- ### Toggle Boolean Flags via HTTP Source: https://context7.com/nigozi/flag4s/llms.txt Use POST requests to enable or disable existing boolean flags. ```bash curl -X POST http://localhost:8080/flags/featureB/enable ``` ```bash curl -X POST http://localhost:8080/flags/featureB/disable ``` -------------------------------- ### Conditional Execution with ifIs Source: https://context7.com/nigozi/flag4s/llms.txt Execute a code block when a flag's value matches a specified value. Handles cases where the flag might not be found. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) val conditionalOp: IO[Unit] = for { flagResult <- flag("featureLevel") result <- flagResult match { case Right(f) => ifIs(f, "advanced") { loadAdvancedFeatures() } case Left(_) => IO.pure(Left(new RuntimeException("Flag not found"))) } _ <- IO(result match { case Right(features) => println(s"Loaded: $features") case Left(e) => println(s"Skipped: ${e.getMessage}") }) } yield () def loadAdvancedFeatures(): List[String] = List("AI", "Analytics", "Automation") conditionalOp.unsafeRunSync() // Output: Loaded: List(AI, Analytics, Automation) ``` -------------------------------- ### POST /set - Update Existing Flag Value Source: https://context7.com/nigozi/flag4s/llms.txt Updates an existing flag's value. Returns `Left` if the flag doesn't exist or if there's a type mismatch. ```APIDOC ## POST /set ### Description Updates an existing flag's value. Returns `Left` if the flag doesn't exist or if there's a type mismatch. ### Method POST ### Endpoint /set ### Parameters #### Request Body - **flag** (object) - Required - The flag object to update. - **key** (string) - Required - The flag's key. - **value** (any) - Required - The new value for the flag. ### Request Example ```json { "key": "apiVersion", "value": "v2.0" } ``` ### Response #### Success Response (200) - **Flag** (object) - The updated flag object. - **key** (string) - The flag's key. - **value** (any) - The flag's new value. #### Error Response (404 Not Found or 400 Bad Request) - **Throwable** (object) - An error indicating the flag was not found or a type mismatch occurred. #### Response Example ```json { "key": "apiVersion", "value": "v2.0" } ``` ``` -------------------------------- ### Create or Update Flag with switchFlag Source: https://context7.com/nigozi/flag4s/llms.txt The `switchFlag` function sets a flag's value, creating it if it doesn't exist. It performs type validation on existing flags. This function can be used for toggling flag states. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) // Create or update flag (upsert behavior) val result: IO[Either[Throwable, Flag]] = switchFlag("featureX", true) result.unsafeRunSync() match { case Right(f) => println(s"Flag set: ${f.key} = ${f.value}") case Left(e) => println(s"Error: ${e.getMessage}") } // Toggle flag value for { _ <- switchFlag("featureX", true) // Enable _ <- switchFlag("featureX", false) // Disable } yield () // Output: Flag set: featureX = true ``` -------------------------------- ### Delete Flags via HTTP Source: https://context7.com/nigozi/flag4s/llms.txt Remove flags from the store using DELETE requests. ```bash curl -X DELETE http://localhost:8080/flags/featureA ``` ```bash curl -X DELETE http://localhost:8080/flags/nonExistent ``` -------------------------------- ### Enable/Disable Boolean Flag Source: https://context7.com/nigozi/flag4s/llms.txt Enable or disable a boolean feature flag using dedicated POST endpoints. ```APIDOC ## POST /flags/{key}/enable ## POST /flags/{key}/disable ### Description Enables or disables a boolean feature flag. ### Method POST ### Endpoint /flags/{key}/enable /flags/{key}/disable ### Parameters #### Path Parameters - **key** (string) - Required - The key of the flag to enable or disable. ### Response #### Success Response (200) - **value** (boolean) - The new state of the flag (true for enabled, false for disabled). ### Response Example ```json true ``` ``` -------------------------------- ### Update Existing Flag with set Source: https://context7.com/nigozi/flag4s/llms.txt Use `set` to update the value of an existing flag. It returns `Left` if the flag does not exist or if there is a type mismatch. This operation requires fetching the flag first. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) // Get flag and update its value val updateOp: IO[Either[Throwable, Flag]] = for { flagResult <- flag("apiVersion") updated <- flagResult match { case Right(f) => set(f, "v2.0") case Left(e) => IO.pure(Left(e)) } } yield updated updateOp.unsafeRunSync() match { case Right(f) => println(s"Updated: ${f.key} = ${f.value}") case Left(e) => println(s"Error: ${e.getMessage}") } // Output: Updated: apiVersion = "v2.0" ``` -------------------------------- ### Delete Flag Source: https://context7.com/nigozi/flag4s/llms.txt Remove a feature flag from the store. ```APIDOC ## DELETE /flags/{key} ### Description Deletes a feature flag from the store. ### Method DELETE ### Endpoint /flags/{key} ### Parameters #### Path Parameters - **key** (string) - Required - The key of the flag to delete. ### Response #### Success Response (200) - (empty body) #### Error Response (400) - **message** (string) - Error message if the flag does not exist. ### Response Example (Success) (empty body) ### Response Example (Error) ```json "failed to delete flag nonExistent" ``` ``` -------------------------------- ### Conditional Execution with ifEnabled Source: https://context7.com/nigozi/flag4s/llms.txt Execute a code block specifically when a boolean flag is true. Ensure the flag is retrieved and handled for potential errors before calling ifEnabled. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) val conditionalOp: IO[Unit] = for { flagResult <- flag("experimentalUI") result <- flagResult match { case Right(f) => ifEnabled(f) { renderExperimentalUI() } case Left(_) => IO.pure(Left(new RuntimeException("Flag not found"))) } _ <- IO(result match { case Right(ui) => println(s"Rendered: $ui") case Left(e) => println(s"Skipped: ${e.getMessage}") }) } yield () def renderExperimentalUI(): String = "Experimental UI rendered" conditionalOp.unsafeRunSync() // Output: Rendered: Experimental UI rendered ``` -------------------------------- ### Check Boolean Flag Status with enabled Source: https://context7.com/nigozi/flag4s/llms.txt The `enabled` function checks if a boolean flag's value is `true`. It requires the flag to be fetched first and handles potential errors during flag retrieval. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) val checkEnabled: IO[Unit] = for { flagResult <- flag("darkMode") isEnabled <- flagResult match { case Right(f) => enabled(f) case Left(_) => IO.pure(false) } _ <- IO(println(s"Dark mode enabled: $isEnabled")) } yield () checkEnabled.unsafeRunSync() // Output: Dark mode enabled: true ``` -------------------------------- ### Check Flag Value Equality with is Source: https://context7.com/nigozi/flag4s/llms.txt Use `is` to check if a flag's value matches a specified value. This function works with any type that has a Circe Encoder. It returns `false` if the flag cannot be retrieved. ```scala import flag4s.core._ import flag4s.core.store.RedisStore import cats.effect.IO import scala.concurrent.ExecutionContext.Implicits.global implicit val store: RedisStore = RedisStore("localhost", 6379) val checkValue: IO[Unit] = for { flagResult <- flag("environment") isProd <- flagResult match { case Right(f) => is(f, "production") case Left(_) => IO.pure(false) } _ <- IO(println(s"Is production: $isProd")) } yield () checkValue.unsafeRunSync() // Output: Is production: true ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.