Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - URL with Query String Parser and Builder DSL

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?

like image 690
theon Avatar asked Nov 19 '12 22:11

theon


3 Answers

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
like image 124
theon Avatar answered Oct 15 '22 00:10

theon


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("?", "&", "")
}
like image 36
ryryguy Avatar answered Oct 15 '22 01:10

ryryguy


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.

like image 22
pme Avatar answered Oct 15 '22 01:10

pme