使用Akka HTTP查询GET请求的参数(正式名称为Spray)

时间:2015-08-10 21:55:19

标签: akka spray akka-http

Akka HTTP(正式名称为Spray)的一个特性是它能够自动编组和解组来自json的数据到案例类等。我已经成功地使其运行良好。

目前,我正在尝试创建一个使用查询参数执行GET请求的HTTP客户端。代码目前看起来像这样:

val httpResponse: Future[HttpResponse] =
  Http().singleRequest(HttpRequest(
    uri = s"""http://${config.getString("http.serverHost")}:${config.getInt("http.port")}/""" +
          s"query?seq=${seq}" +
          s"&max-mismatches=${maxMismatches}" +
          s"&pam-policy=${pamPolicy}"))

嗯,那不太好看。如果我可以传入一个包含查询参数的case类,并且让Akka HTTP自动生成查询参数,就像它对json一样。 (另外,Akka HTTP的服务器端有一种解析GET查询参数的优雅方式,所以人们会认为它也会有一种优雅的方式来生成它们。)

我想做以下事情:

val httpResponse: Future[HttpResponse] =
  Http().singleRequest(HttpRequest(
    uri = s"""http://${config.getString("http.serverHost")}:${config.getInt("http.port")}/query""",
    entity = QueryParams(seq = seq, maxMismatches = maxMismatches, pamPolicy = pamPolicy)))

只是,以上情况并没有实际发挥作用。

我想用Akka HTTP以某种方式做什么?或者我只是需要以老式的方式做事?即,显式生成查询参数,就像我在上面的第一个代码块中一样。

(我知道如果我要将其从GET更改为POST,我可能会让它更像我希望它工作,从那时起我就可以获得自动转换的POST请求的内容从案例类到json,但我真的不希望在这里这样做。)

2 个答案:

答案 0 :(得分:25)

您可以利用Uri课程来完成您想要的工作。它提供了多种方法,使用withQuery方法将一组参数传递到查询字符串中。例如,你可以这样做:

val params = Map("foo" -> "bar", "hello" -> "world")
HttpRequest(Uri(hostAndPath).withQuery(params))

或者

HttpRequest(Uri(hostAndPath).withQuery(("foo" -> "bar"), ("hello" -> "world")))

答案 1 :(得分:1)

显然,这可以通过改变扩展Akka HTTP的功能来实现,但是对于你需要的东西(只是构建查询字符串的一种更整洁的方式),你可以用一些scala乐趣来做到这一点:

type QueryParams = Map[String, String]

object QueryParams {

  def apply(tuples: (String, String)*): QueryParams = Map(tuples:_*)
}

implicit class QueryParamExtensions(q: QueryParams) {

  def toQueryString = "?"+q.map{
    case (key,value) => s"$key=$value" //Need to do URL escaping here?
  }.mkString("&")
}

implicit class StringQueryExtensions(url: String) {
  def withParams(q: QueryParams) =
    url + q.toQueryString
}

val params = QueryParams(
  "abc" -> "def",
  "xyz" -> "qrs"
)

params.toQueryString // gives ?abc=def&xyz=qrs

"http://www.google.com".withParams(params) // gives http://www.google.com?abc=def&xyz=qrs