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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With