aboutsummaryrefslogtreecommitdiff
path: root/docs/backends/custom.rst
diff options
context:
space:
mode:
authoradamw <adam@warski.org>2017-10-18 14:20:26 +0200
committeradamw <adam@warski.org>2017-10-18 14:20:26 +0200
commit21c4700bbe8cf37d7b9feacc5afdf64357604d8f (patch)
tree50cd74646955bae495296b1d9a212ac412a75b7c /docs/backends/custom.rst
parent6e109a964383bfe5e2be04f65fa7cc1356a97cbe (diff)
downloadsttp-21c4700bbe8cf37d7b9feacc5afdf64357604d8f.tar.gz
sttp-21c4700bbe8cf37d7b9feacc5afdf64357604d8f.tar.bz2
sttp-21c4700bbe8cf37d7b9feacc5afdf64357604d8f.zip
More docs
Diffstat (limited to 'docs/backends/custom.rst')
-rw-r--r--docs/backends/custom.rst63
1 files changed, 60 insertions, 3 deletions
diff --git a/docs/backends/custom.rst b/docs/backends/custom.rst
index 4dd5208..0820a26 100644
--- a/docs/backends/custom.rst
+++ b/docs/backends/custom.rst
@@ -3,7 +3,7 @@
Custom backends, logging, metrics
=================================
-It is also entirely possible to write custom own backend (if doing so, please consider contributing!) or wrapping an existing one. One can even write completely generic wrappers for any delegate backend, as each backend comes equipped with a monad for the response type. This brings the possibility to ``map`` and ``flatMap`` over responses.
+It is also entirely possible to write custom backends (if doing so, please consider contributing!) or wrap an existing one. One can even write completely generic wrappers for any delegate backend, as each backend comes equipped with a monad for the response type. This brings the possibility to ``map`` and ``flatMap`` over responses.
Possible use-cases for wrapper-backend include:
@@ -11,7 +11,64 @@ Possible use-cases for wrapper-backend include:
* capturing metrics
* request signing (transforming the request before sending it to the delegate)
-To pass some context to wrapper-backends, requests can be *tagged*. Each ``RequestT`` instance contains a ``tags: Map[String, Any]`` field. This is unused by http, but can be used e.g. to pass a metric name or logging context.
+Request tagging
+---------------
-Example backend logging
+Each request contains a ``tags: Map[String, Any]`` map. This map can be used to tag the request with any backend-specific information, and isn't used in any way by sttp itself.
+Tags can be added to a request using the ``def tag(k: String, v: Any)`` method, and read using the ``def tag(k: String): Option[Any]`` method.
+
+Backends, or backend wrappers can use tags e.g. for logging, passing a metric name, using different connection pools, or even different delegate backends.
+
+Example backend wrapper
+-----------------------
+
+Below is an example on how to implement a backend wrapper, which sends metrics for completed requests and wraps any ``Future``-based backend::
+
+ // the metrics infrastructure
+ trait MetricsServer {
+ def reportDuration(name: String, duration: Long): Unit
+ }
+
+ class CloudMetricsServer extends MetricsServer {
+ override def reportDuration(name: String, duration: Long): Unit = ???
+ }
+
+ // the backend wrapper
+ class MetricWrapper[S](delegate: SttpBackend[Future, S],
+ metrics: MetricsServer)
+ extends SttpBackend[Future, S] {
+
+ override def send[T](request: Request[T, S]): Future[Response[T]] = {
+ val start = System.currentTimeMillis()
+
+ def report(metricSuffix: String): Unit = {
+ val metricPrefix = request.tag("metric").getOrElse("?")
+ val end = System.currentTimeMillis()
+ metrics.reportDuration(metricPrefix + "-" + metricSuffix, end - start)
+ }
+
+ delegate.send(request).andThen {
+ case Success(response) if response.is200 => report("ok")
+ case Success(response) => report("notok")
+ case Failure(t) => report("exception")
+ }
+ }
+
+ override def close(): Unit = delegate.close()
+
+ override def responseMonad: MonadError[Future] = delegate.responseMonad
+ }
+
+ // example usage
+ implicit val backend = new MetricWrapper(
+ AkkaHttpBackend(),
+ new CloudMetricsServer()
+ )
+
+ sttp
+ .get(uri"http://company.com/api/service1")
+ .tag("metric", "service1")
+ .send()
+
+