为任意JSON创建一个"解码器"

Tom*_*ams 3 scala finch graphql sangria circe

我正在使用Finch,Circe和Sangria为API构建GraphQL端点.将variables通过在GraphQL查询来基本上是任意的JSON对象(假设没有嵌套).例如,在我的测试代码中String,这是两个例子:

val variables = List(
  "{\n  \"foo\": 123\n}",
  "{\n  \"foo\": \"bar\"\n}"
)
Run Code Online (Sandbox Code Playgroud)

Sangria API期望这些类型Map[String, Any].

我已经尝试了很多方法但到目前为止Decoder还没能在Circe 写一个.任何帮助赞赏.

ten*_*shi 5

Sangria API期望Map [String,Any]的类型

这不是真的.在sangria中执行的变量可以是任意类型T,唯一要求是InputUnmarshaller[T]为它设置类型类的实例.所有编组集成库都提供了InputUnmarshaller对应的JSON AST类型的实例.

这意味着sangria-circe定义了InputUnmarshaller[io.circe.Json]你可以导入它import sangria.marshalling.circe._.

这是一个小而独立的例子,说明如何使用circe Json作为变量:

import io.circe.Json

import sangria.schema._
import sangria.execution._
import sangria.macros._

import sangria.marshalling.circe._

val query =
  graphql"""
    query ($$foo: Int!, $$bar: Int!) {
      add(a: $$foo, b: $$bar)
    }
  """

val QueryType = ObjectType("Query", fields[Unit, Unit](
  Field("add", IntType,
    arguments = Argument("a", IntType) :: Argument("b", IntType) :: Nil,
    resolve = c ? c.arg[Int]("a") + c.arg[Int]("b"))))

val schema = Schema(QueryType)

val vars = Json.obj(
  "foo" ? Json.fromInt(123),
  "bar" ? Json.fromInt(456))

val result: Future[Json] =
  Executor.execute(schema, query, variables = vars)
Run Code Online (Sandbox Code Playgroud)

正如您在此示例中所看到的,我将io.circe.Json变量用作执行变量.执行将产生以下结果JSON:

{
  "data": {
    "add": 579
  }
}
Run Code Online (Sandbox Code Playgroud)