0

我想测试我的 Caliban Http4s Web 服务。

Http4sAdapter它用于GraphQLRequest对请求正文进行建模。

case class GraphQLRequest(
   query: String,
   operationName: Option[String],
   variables: Option[Map[String, InputValue]])
...
query    <- req.attemptAs[GraphQLRequest].value.absolve
...

所以我认为在客户端我也可以使用它。

一个简单的请求有效:

 GraphQLRequest("""query{
                         |  characters(origin: EARTH) {
                         |    name
                         |    nicknames
                         |    origin
                         |  }
                         |}""".stripMargin, None, None)

但是如果我使用变量它不会:

GraphQLRequest("""query($origin: String){
                 |  characters(origin: $origin) {
                 |    name
                 |    nicknames
                 |    origin
                 |  }
                 |}""".stripMargin, None, Some(Map("origin" -> StringValue("EARTH"))))

它只是挂起 - 甚至没有例外。

我尝试使用0.4.2and 0.5.0

我添加了一个要点来显示客户端代码。它使用CirceSttp客户端要点

4

1 回答 1

1

主要问题可以在您的要点中看到:编码为 JSON 的变量不是服务器所期望的。

您目前拥有:

"origin": {
  "StringValue": {
    "value": "EARTH"
  }
}

你应该只有:

"origin": "EARTH"

该值InputValue在 Caliban 中是 an,CalibanEncoder为 Circe 提供了 an。但是,您似乎正在使用 Circe 通用自动推导,它没有采用 Caliban Encoder,而是尝试InputValue自行推导,给出了不正确的结果。

我建议在 circe-generic 中使用半自动推导,甚至使用 circe-derivation 来Encoder正确获取 Caliban 的。circe-generic 示例:

val req = GraphQLRequest(
  """query($origin: String){
    |  characters(origin: $origin) {
    |    name
    |    nicknames
    |    origin
    |  }
    |}""".stripMargin,
  None,
  Some(Map("origin" -> StringValue("EARTH")))
)

import io.circe.syntax._
import io.circe.generic.semiauto._
implicit val enc = deriveEncoder[GraphQLRequest]

println(req.asJson)

给出预期的 JSON:

{
  "query" : "query($origin: String){\n  characters(origin: $origin) {\n    name\n    nicknames\n    origin\n  }\n}",
  "operationName" : null,
  "variables" : {
    "origin" : "EARTH"
  }
}
于 2020-01-30T08:02:23.470 回答