Skip to content

Instantly share code, notes, and snippets.

@lucmclaren
Last active December 4, 2018 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucmclaren/0f8c5903d33c33f70db46ab57fb8b246 to your computer and use it in GitHub Desktop.
Save lucmclaren/0f8c5903d33c33f70db46ab57fb8b246 to your computer and use it in GitHub Desktop.
[Draft] Feature toggles with Toguru

Feature Toggles with Toguru

Introduction

For those of you who don't know what feature toggles are, I will give a short introduction:

Did you ever have problems with feature branches? Then you probably know the cumbersome merge process of diverged branches. In this case, feature toggles are pretty handy because they allow you to develop on one major branch in parallel.

Basically, you build a switch into your code which you can activate at runtime. You can develop your features and are still able to continuously deliver with your CI/CD tool, without requiring additional branches which have to be merged and built later on. Another benefit is you can use feature toggles for rollouts which I will show you later on.

If you want to know more about the various flavors of feature toggles I suggest reading this blog post on Martin Fowler’s blog: Feature Toggles

What is this Toguru anyway?!

The name "Toguru"(トグル) is Japanese which translated to English means "toggle". It's also the acronym for "Toggle Guru".

Toguru is a Scala/Play based application. It helps you to manage your toggles with a REST API and/or the Toguru Panel which is a web GUI where you can see what’s going on. There already is a Scala client. I will show with an example how to use it and what you can do with it. Toguru is also capable of releasing your features, so you can do things like Canary releases or filtering your rollout by custom attributes (like country) and a rollout percentage.

How to use

In following, I will show you a basic example on how to use the Scala client and how to interact with Toguru’s API to have a working feature toggle implemented.

Creating an Example App

I started with the Scala Play Seed template. It's very easy if you have SBT installed just execute this command:

sbt new playframework/play-scala-seed.g8

Then start SBT (the first time it'll take some time to load all the libraries) and run the Play Scala template with sbt run.

Now I have my example app up and running on port 9000.

Using Toguru Scala Client

First, I add the AutoScout24 maven repo and the Scala client in my build.sbt file.

build.sbt

resolvers += Resolver.bintrayRepo("autoscout24", "maven")
libraryDependencies += "com.autoscout24" %% "toguru-scala-client" % "1.0.0"

Then, I import the client I need in my HomeController.scala

HomeController.scala

import toguru.play._
import toguru.play.PlaySupport._
import toguru.api._

Next, I add a cookie which is needed by Toguru to identify unique users. You can name that cookie however you want, but you should use an UUID as value. Finally, I also add the client with an example toggle, so that the Toguru server which I will run locally with Docker in the next step has a toggle to deal with.

Here my very simple version of a toggle:

HomeController.scala

// Setting up the toguru client
val client: PlayClientProvider = { implicit request =>
  ClientInfo(uuidFromCookieValue("UniqueUserId"), forcedToggle)
}

// Telling the client which toguru server to use (in this case my locally running docker instance)
val toguru = PlaySupport.toguruClient(client, "http://localhost:9090")

// and of course a toggle for my example
val toggle = Toggle("example-toggle", default = Condition.Off)

def uuid = java.util.UUID.randomUUID.toString

// I'm setting a UUID so I can use it to identify unique users, this is needed by toguru scala client
def index = Action { implicit request =>
  implicit val toggling = toguru(request)
  request.cookies.get("UniqueUserId") match {
    case Some(_)  => Ok(views.html.index(toggle))
    case None     => Ok(views.html.index(toggle)).withCookies(Cookie("UniqueUserId", uuid))
  }
}

index.scala.html

@import toguru.api.Toggle
@import toguru.api.Toggling
@(toggle: Toggle)(implicit toggling: Toggling)

@main("Welcome to Play") {
  @if(toggle.isOn) {
      <h1>Example toggle is activated</h1>
  } else {
      <h1>Our toggle is deactivated</h1>
  }

}

Hands on Toguru server

What I do next is to run the Toguru server locally with Docker. Starting Toguru locally is very easy. You just have to install docker-compose and then use the docker-compose file that comes with Toguru. In my example, though I changed the default port to port 9090 in the docker-compose.yaml.

git clone git@github.com:AutoScout24/toguru.git
cd toguru


# Replacing dev conf with application conf(to be more realistic)
cp conf/application.conf conf/dev.conf

# adding an API key
gem install bcrypt

UUID=$(uuidgen)
HASH=$(ruby -e "require 'bcrypt'; puts BCrypt::Password.create(\"$UUID\")")
HASH_ESCAPED=$(printf "%q" "$HASH")

echo "MyApiKey: $UUID"
echo "HashedApiKey: $HASH"

sed -i '' "s;\[];\[{\"name\": \"ExampleKey\", \"hash\": \"${HASH_ESCAPED}\"}\];g" conf/dev.conf

# Building and starting a local Toguru server including Postgres
docker-compose up --build

Fun with toggles

Now with my Toguru server up and running, I will add my already implemented toggle to Toguru server via curl, of course, you can use postman or else also.

Hint: The first request may take longer because Play compiles at the first request

# Creating an example toggle
curl -H "Authorization: api-key 02EEDAF2-FC23-453B-82E5-D177F8E9280D" -XPOST http://localhost:9090/toggle -d '{"name":"Example Toggle","description":"Toguru demo toggle", "tags":{"example":"somevalue"}}'


# Creating an activation condition
curl -H "Authorization: api-key 02EEDAF2-FC23-453B-82E5-D177F8E9280D" -XPOST http://localhost:9090/toggle/example-toggle/activations \
  -d '{ "rollout": { "percentage": 100 } }'

I created an activation which has a rollout percentage of 100%. Then I start my previously created Scala Play example app, and now my toggle should be active.

Toggle activated

For demonstration purposes, I will delete the activation again.

# Deleting the activation
curl -H "Authorization: api-key 02EEDAF2-FC23-453B-82E5-D177F8E9280D" -XDELETE http://localhost:9090/toggle/example-toggle/activations/0

Toggle deactivated

Finally, I shut my local Toguru down with Ctrl-C. Then, I clean up the containers with docker-compose down.

Playing God

For testing purposes, there is also a "God Mode" where you can force your toggle to be activated. Let's assume you have the situation that you're deploying your app and want to test a new feature. One way of doing this is with a query parameter in the URL.

You have to add “toguru” as query parameter where the key is the "toggle id" and a value of "true" or "false". You can add multiple toggles with the "|" separator.

http://localhost:9000/?toguru=example-toggle=true

Now the toggle is activated only for your client whilst the application is running. This can be very helpful when testing new features without having them activated. You can even use this for automated testing of your new feature.

Conclusion

I hope I could give you some insights about what Toguru can be used for. There is, of course, more you can do with Toguru.

In my example, I created a simple app with an example feature toggle. I demonstrated how to switch a toggle on and off again via the REST API of my Toguru server running locally with Docker.

With Custom Attributes, you can do even more. For example, if you have your app running in several countries, you can set a custom attribute to distinguish between them. This way you can distribute your feature just in one specific country. Of course, you can use this with any information you can find on the client side if you enrich the client info of the Toguru Scala Client.

If you want to check out the demo, take a look at my Examples

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment