In Scala how do I build up a URL with query string parameters programmatically?
Also how can I parse a String
containing a URL with query string parameters into a structure that allows me to edit the query string parameters programmatically?
In Scala how do I build up a URL with query string parameters programmatically?
Also how can I parse a String
containing a URL with query string parameters into a structure that allows me to edit the query string parameters programmatically?
Spray has a very efficient URI parser. Usage is like so:
import spray.http.Uri
val uri = Uri("http://example.com/test?param=param")
You can set the query params like so:
uri withQuery ("param2" -> "2", "param3" -> 3")
The following library can help you parse and build URLs with query string parameters (Disclaimer: This is my own library): https://github.com/lemonlabsuk/scala-uri
It provides a DSL for building URLs with query strings:
val uri = "http://example.com" ? ("one" -> 1) & ("two" -> 2)
You can parse a uri and get the parameters into a Map[String,List[String]]
like so:
val uri = parseUri("http://example.com?one=1&two=2").query.params
Theon's library looks pretty nice. But if you just want a quickie encode method, I have this one. It deals with optional parameters, and also will recognize JsValues from spray-json and compact print them before encoding. (Those happen to be the two things I have to worry about, but you could easily extend the match block for other cases you want to give special handling to)
import java.net.URLEncoder
def buildEncodedQueryString(params: Map[String, Any]): String = {
val encoded = for {
(name, value) <- params if value != None
encodedValue = value match {
case Some(x:JsValue) => URLEncoder.encode(x.compactPrint, "UTF8")
case x:JsValue => URLEncoder.encode(x.compactPrint, "UTF8")
case Some(x) => URLEncoder.encode(x.toString, "UTF8")
case x => URLEncoder.encode(x.toString, "UTF8")
}
} yield name + "=" + encodedValue
encoded.mkString("?", "&", "")
}
sttp provides a great URI interpolator for this.
See here the Documentation
Here its example:
import sttp.client._
import sttp.model._
val user = "Mary Smith"
val filter = "programming languages"
val endpoint: Uri = uri"http://example.com/$user/skills?filter=$filter"
assert(endpoint.toString ==
"http://example.com/Mary%20Smith/skills?filter=programming+languages")
As you can see it automatically encodes the needed parts.
Dispatch hasn't been mentioned yet.
https://dispatchhttp.org/Defining+requests.html
val myRequest = host("somehost.com") / "some" / "path" <<? Map("id" -> "12345")
also useful: https://github.com/mobiworx/urlifier
val url = (http || "some-domain".de) ? german & version(1) & foobar
url.toString
Try KFoundation's URL class. It is both a builder and a parser.
E.g.
val url1 = URL("http://exampel.net/path")
val url2 = url1/"subpath" // -> http://exampel.net/path/subpath
val url3 = url2?("key"->"value") // -> http://exampel.net/path/subpath?key=value
API Doc: https://mscp.co/resouces/apidoc/kfoundation/scala/0.3/net/kfoundation/scala/io/URL.html Dependency: https://search.maven.org/artifact/net.kfoundation/kfoundation-scala_2.13/0.3.1/jar