是否可以在 Caliban 中为客户端使用 GraphQLRequest?
Is it possible to use GraphQLRequest for a client in Caliban?
我想测试我的 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.2
和 0.5.0
。
我添加了一个 Gist 来显示客户端代码。它使用 Circe 和 Sttp:Client Gist
主要问题可以在你的要点中看出:编码到 JSON 中的变量不是服务器所期望的。
您目前拥有:
"origin": {
"StringValue": {
"value": "EARTH"
}
}
你应该只有:
"origin": "EARTH"
该值在卡利班中是 InputValue
,而卡利班为 Circe 提供了一个 Encoder
。但是,您似乎正在使用 Circe 通用自动推导,它没有获取 Caliban 的 Encoder
而是试图自己推导 InputValue
,给出了不正确的结果。
我建议在 circe-generic 中使用半自动推导,甚至使用 circe-derivation 来正确获取 Caliban 的 Encoder
。
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"
}
}
我想测试我的 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.2
和 0.5.0
。
我添加了一个 Gist 来显示客户端代码。它使用 Circe 和 Sttp:Client Gist
主要问题可以在你的要点中看出:编码到 JSON 中的变量不是服务器所期望的。
您目前拥有:
"origin": {
"StringValue": {
"value": "EARTH"
}
}
你应该只有:
"origin": "EARTH"
该值在卡利班中是 InputValue
,而卡利班为 Circe 提供了一个 Encoder
。但是,您似乎正在使用 Circe 通用自动推导,它没有获取 Caliban 的 Encoder
而是试图自己推导 InputValue
,给出了不正确的结果。
我建议在 circe-generic 中使用半自动推导,甚至使用 circe-derivation 来正确获取 Caliban 的 Encoder
。
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"
}
}