17

Akka HTTP (以前は Spray と呼ばれていました) の機能の 1 つは、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}"))

まあ、それはそれほどきれいではありません。json の場合と同様に、クエリ パラメーターを含むケース クラスを渡すだけで、Akka HTTP にクエリ パラメーターを自動的に生成させることができればよいのですが。(また、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 要求の内容を取得できるからです。 class を json に変換しますが、ここではあまりやりたくありません。)

4

2 に答える 2

30

Uriクラスを活用して、必要なことを行うことができます。メソッドを使用して一連のパラメーターをクエリ文字列に取得する方法は複数ありますwithQuery。たとえば、次のようなことができます。

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

または

HttpRequest(Uri(hostAndPath).withQuery(("foo" -> "bar"), ("hello" -> "world")))
于 2015-08-11T10:50:50.067 に答える
0

明らかに、これは Akka HTTP の拡張機能を変更することで実行できますが、必要なもの (クエリ文字列を作成するためのより適切な方法) については、いくつかの scala fun を使用して実行できます。

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
于 2015-08-11T08:47:16.800 に答える