diff options
author | adamw <adam@warski.org> | 2017-07-10 15:18:56 +0200 |
---|---|---|
committer | adamw <adam@warski.org> | 2017-07-10 15:18:56 +0200 |
commit | 74a1d680d5f093ab45b31553bf5f5ccd08d5ae16 (patch) | |
tree | 424a9aa8d4f74e668d7ed999a180c5f3a758c7cc | |
parent | 63e244227ca9d7824d9ec99b558d5bcedf704136 (diff) | |
download | sttp-74a1d680d5f093ab45b31553bf5f5ccd08d5ae16.tar.gz sttp-74a1d680d5f093ab45b31553bf5f5ccd08d5ae16.tar.bz2 sttp-74a1d680d5f093ab45b31553bf5f5ccd08d5ae16.zip |
URI interpolator readme, more tests
-rw-r--r-- | README.md | 43 | ||||
-rw-r--r-- | core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala | 13 | ||||
-rw-r--r-- | tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala | 8 |
3 files changed, 60 insertions, 4 deletions
@@ -49,6 +49,49 @@ implicit val handler = HttpConnectionSttpHandler Any request definition starts from `sttp`: the empty request. This can be further customised, each time yielding a new, immutable request description (unless a mutable body is set on the request, such as a byte array). +## URI interpolator + +Using the URI interpolator it's possible to conveniently create `java.net.URI` instances, which can then be used +to specify request endpoints, for example: + +```scala +import com.softwaremill.sttp._ +import java.net.URI + +val user = "Mary Smith" +val filter = "programming languages" + +val endpoint: URI = uri"http://example.com/$user/skills?filter=$filter" +``` + +Any values embedded in the URI will be URL-encoded, taking into account the context (e.g., the whitespace in `user` will +be %-encoded as `%20D`, while the whitespace in `filter` will be query-encoded as `+`). + +The possibilities of the interpolator don't end here. Other supported features: + +* parameters can have optional values: if the value of a parameter is `None`, it will be removed +* maps, sequences of tuples and sequences of values can be embedded in the query part. They will be expanded into +query parameters. Maps and sequences of tuples can also contain optional values, for which mappings will be removed +if `None`. +* optional values in the host part will be expanded to a subdomain if `Some`, removed if `None` +* sequences in the host part will be expanded to a subdomain sequence + +A fully-featured example: + +```scala +import com.softwaremill.sttp._ +val secure = true +val scheme = if (secure) "https" else "http" +val subdomains = List("sub1", "sub2") +val vx = Some("y z") +val params = Map("a" -> 1, "b" -> 2) +val jumpTo = Some("section2") +uri"$scheme://$subdomains.example.com?x=$vx&$params#$jumpTo" + +// generates: +// https://sub1.sub2.example.com?x=y+z&a=1&b=2#section2 +``` + ## Request types All requests have type `RequestTemplate[U]`, where `U[_]` specifies if the request method and URL are specified. There diff --git a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala index 294d6ce..4bc2a0b 100644 --- a/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala +++ b/core/src/main/scala/com/softwaremill/sttp/UriInterpolator.scala @@ -163,19 +163,26 @@ object UriInterpolator { override def parseE(e: Any): UriBuilder = e match { case m: Map[_, _] => - val flattenedMap = m.flatMap { + val flattenedM = m.flatMap { case (_, None) => None case (k, Some(v)) => Some((k, v)) case (k, v) => Some((k, v)) } - val newFragments = flattenedMap.map { + val newFragments = flattenedM.map { case (k, v) => (Some(encode(k, query = true)), Some(encode(v, query = true))) } copy(fs = fs ++ newFragments) case s: Seq[_] => - val newFragments = s.map { + val flattenedS = s.flatMap { + case (_, None) => None + case (k, Some(v)) => Some((k, v)) + case None => None + case Some(k) => Some(k) + case x => Some(x) + } + val newFragments = flattenedS.map { case (k, v) => (Some(encode(k, query = true)), Some(encode(v, query = true))) case x => (Some(encode(x, query = true)), None) diff --git a/tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala b/tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala index d7719fd..df26f66 100644 --- a/tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala +++ b/tests/src/test/scala/com/softwaremill/sttp/UriInterpolatorTests.scala @@ -88,7 +88,13 @@ class UriInterpolatorTests extends FunSuite with Matchers { (uri"http://example.com?x=y&${Map("a" -> None)}", s"http://example.com?x=y"), (uri"http://example.com?x=y&${Map("a" -> Some("b"))}", - s"http://example.com?x=y&a=b") + s"http://example.com?x=y&a=b"), + (uri"http://example.com?x=y&${Seq("a" -> None)}", + s"http://example.com?x=y") + ), + "fragments" -> List( + (uri"http://example.com#$v1", s"http://example.com#$v1"), + (uri"http://example.com#$None", s"http://example.com") ), "everything" -> List( (uri"${"http"}://$v1.$v2.com/$v1/$v2?$v1=$v2&$v3=$v4#$v1", |