Name: toguru-scala-client
Owner: AutoScout24
Owner: AutoScout24
Description: Toguru client library for Scala
Created: 2016-09-09 08:20:49.0
Updated: 2017-09-28 07:37:17.0
Pushed: 2018-02-09 09:01:51.0
Homepage: null
Size: 1224
Language: Scala
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Toguru client for Scala applications
Add to your build.sbt
following resolver with dependency:
lvers += Resolver.bintrayRepo("autoscout24", "maven")
aryDependencies += "com.autoscout24" %% "toguru-scala-client" % "(see version number above)",
To toggle code with this client, you need to perform the following steps.
Create a Toguru client - e.g. in the Guice module of your Play application so that it can be injected wherever you need it. For this, you need to define
rt play.api.mvc._
rt toguru.play._
rt toguru.play.PlaySupport._
client: PlayClientProvider = { implicit request =>
ientInfo(uuidFromCookieValue("myVisitor"), forcedToggle)
toguru = PlaySupport.toguruClient(client, "http://localhost:9000")
Define a toggle using a toggle id and a default activation condition, e.g. in an object that contains all your toggles. The activation condition will be fetched from the Toguru server based on the toggle id. The fallback is used if the server can't be reached or the toggle id isn't in the server's toggle state response.
toggle = Toggle("my-toggle", default = Condition.Off)
Now, you can determine the state of your toggle based on the client info and the toggle activation condition from the Toguru server:
icit val toggling = toguru(request)
oggle.isOn)
("Toggle is on")
("Toggle is off")
In a microservice environment, a request to a service can produce multiple sub-requests. When doing feature toggling, it is important to keep the toggle state consistent over the sub-requests for a main request.
To do this you can
Here is how this would look like for a service included via nginx server-side includes:
Defining the service a toggle belongs to: define a tag (e.g. service
) to identify all toggles to be passed along. Using curl, a toggle with id my-toggle
can be associated to the service owning-service
as follows:
-XPUT https://your-endpoint.example.com/toggle/my-toggle -d '{ "tags": { "service" : "owning-service" } }'
Pass the toggle state: In the controller, you can then build a toggle string:
port toguru.implicits.toggle._
either built yourself or built using ToggledRequest
l toggleInfo: TogglingInfo = ...
l toggleString = toggleInfo()
.filter { _.tags.get("service").contains("owning-service") }
.buildString
In your html template (passing through toggleString
), you can then pass the
toggle state using the toguru
query parameter:
tml(s"""<!--#include virtual="/fragment/contentservice/header.html?toguru=${toggleString}" -->""")
If the included service uses Toguru, the toggle state of all toggles having
the service
tag set to owning-service
will be enforced to have the state
determined by the caller service. You can pass along the toggle state by setting:
x-toguru
or toguru
header,toguru
cookie, ortoguru
query parameter.For details, see the forcedToggle method.
The Toguru Scala client offers several convenience utilities, however. To begin with, you can create a toggled controller based on the Toguru client that your controllers can extend from:
rt play.api.mvc._
rt toguru.play._
ract class ToggledController(toguru: PlayToguruClient) extends Controller {
l ToggledAction = PlaySupport.ToggledAction(toguru)
Now you can define your controller with toggled actions and use the toggle defined earlier to control which code gets executed:
s MyController @Inject()(toguru: PlayToguruClient) extends ToggledController(toguru) {
f myAction = ToggledAction { implicit request =>
if(toggle.isOn)
Ok("Toggle is on")
else
Ok("Toggle is off")
the request gets enriched with toggling information that is passed into the toggle.isOn method.
If you need to enrich the request yourself or can't use PlaySupport's
ToggledAction, you can either apply the Toggling
trait to your request:
s MyRequest[A](toguru: PlayToguruClient, request : Request[A])
extends WrappedRequest[A](request) with Toggling {
erride val client = toguru.clientProvider(request)
erride val activations = toguru.activationsProvider()
Alternatively, you can always create the toggle information yourself:
s MyControllerWithOwnTogglingInfo @Inject()(toguru: PlayToguruClient) extends Controller {
f myAction = Action { request =>
implicit val toggling = toguru(request)
if(toggle.isOn)
Ok("Toggle is on")
else
Ok("Toggle is off")
ClientInfo
provides means to enrich it with custom attributes. When Creating
a ClientInfo.Provider
, attributes can be added by using withAttribute
.
PlaySupport
offers fromCookie
and fromHeader
methods that allow set
custom attribute from a cookie value or a request header, respectively.
Note that the custom attribute will not be set if the cookie or header is
missing.
For example, setting the custom attribute from a cookie named culture
can be
done like this:
client: PlayClientProvider = { implicit request =>
ientInfo(uuidFromCookieValue("myVisitor"), forcedToggle).withAttribute(fromCookie("culture"))
By this, the activation of a toggle can be controlled based on the value of custom attributes.
In your tests, you can also define different activation conditions by using the TestActivations class.
rt toguru.test.TestActivations
toguruClient = PlaySupport.testToguruClient(client, TestActivations(toggle -> Condition.On)())
controller = new MyController(toguruClient)
see the PlaySupport spec for full usage examples in Scala Play.
Copyright © 2017 AutoScout24 GmbH.
Distributed under the MIT License.