当前位置: 首页 > 知识库问答 >
问题:

带有Sangria的GraphQL模式

左博学
2023-03-14

我正在查看用Scala编写GraphQL服务器的Sangria库。但奇怪的是,同一个类型系统必须实现两次:(1)作为GraphQL类型声明的一部分,(2)也是在服务器端,作为Scala case类,附带ObjectType、InterfaceType等。

在Scala中硬编码类型系统尤其令人厌烦,因为我的目的是能够CRUD任意形状的聚合,其中每个形状都被定义为类型的GraphQL集合。例如,假设Shape类型的实例包含作为字段的GraphQL文档;Entity类型的实例具有对其形状的引用,并且还包含在该形状中定义的形状的Json对象。

case class Shape(id: String, name: String, doc: sangria.ast.Document)
case class Entity(id: String, name: String, shape: Shape, content: JsValue)

例如,如果形状文档如下所示:

type Person {
  firstName: String!
  lastName: String!
  age: Int
}
{
  "firstName": "John",
  "lastName": "Smith",
  "age": 30
}

从包含类型声明的GraphQL文档以编程方式生成GraphQL模式是否有现成的方法?

共有1个答案

山煜祺
2023-03-14

对于这种动态用例,sangria提供了一种从GraphQL IDL构建模式的方法。以下是如何实现的(我稍微简化了您的示例,但当所有这些数据都来自单独的类(如shapeentity)时,也可以实现相同的操作):

import sangria.ast._
import sangria.schema._
import sangria.macros._
import sangria.marshalling.sprayJson._
import sangria.execution.Executor

import scala.concurrent.ExecutionContext.Implicits.global
import spray.json._

val schemaAst =
  gql"""
    type Person {
      firstName: String!
      lastName: String!
      age: Int
    }

    type Query {
      people: [Person!]
    }
  """

val schema = Schema.buildFromAst(schemaAst, builder)

val query =
  gql"""
    {
      people {
        firstName
        age
      }
    }
  """

val data =
  """
    {
      "people": [{
        "firstName": "John",
        "lastName": "Smith",
        "age": 30
      }]
    }
  """.parseJson

val result = Executor.execute(schema, query, data)

为了定义resolve函数的生成方式,您需要创建一个自定义架构生成器,如下面这样,并重写resolvefield方法:

val builder =
  new DefaultAstSchemaBuilder[JsValue] {
    override def resolveField(typeDefinition: TypeDefinition, definition: FieldDefinition) =
      typeDefinition.name match {
        case "Query" ⇒
          c ⇒ c.ctx.asJsObject.fields get c.field.name map fromJson
        case _ ⇒
          c ⇒ fromJson(c.value.asInstanceOf[JsObject].fields(c.field.name))
      }

    def fromJson(v: JsValue) = v match {
      case JsArray(l) ⇒ l
      case JsString(s) ⇒ s
      case JsNumber(n) ⇒ n.intValue()
      case other ⇒ other
    }
  }

执行此示例时,您将看到以下JSONresult:

{
  "data": {
    "people": [{
      "firstName": "John",
      "age": 30
    }]
  }
}
 类似资料:
  • 当客户机发送请求时,我想知道客户机请求的数据字段是什么。例如 在上面的请求中,客户端请求了用户的字段和字段。在执行查询时,我如何知道/获得桑格利亚酒-graql服务器中的这些指定字段,即名称和地址?

  • 目前,我正在从这里学习sangria-graphql。然而,我找不到任何关于突变(添加,更新,删除)的文档。还有,谷歌也不会帮我多少。你们能给我提供什么好的资源吗?

  • Sangria.parser.SyntaxError:解析GraphQL查询时出现语法错误。输入结尾意外,应为union、Comments、INTERNECT、SPALEAR、enum、type、inputType或directive(第1行第79列):“Query FetchPokemons{\n pokemonsWithHeight(Height:100){\n NAME\n}\n}” 但是在

  • Sangria 是 Scala GraphQL 的实现。 示例代码: {  "data": {    "hero": {      "name": "R2-D2",      "friends": [        {          "name": "Luke Skywalker"        },        {          "name": "Han Solo"        },

  • GraphQL和Java(Spring)完全搞砸了。有多个项目,多个例子,但完全不一致。 Spring引导支持 异步/并行DataFetcher 批处理DataFetcher 用GraphQLendpoint连接多个服务(可能超出范围) 分页/筛选

  • 我正在玩GraphQL和Spring Boot,但我在这个问题上停留了一段时间。 首先,这是我的build.gradle: 我有一个实体,比如说-Dog,一个存储库,一个服务,一个Mutator和一个查询。在/resources中,我有。 但由于某些原因,我无法启动应用程序。错误消息如下:。当我删除对它启动,但找不到模式。 有什么想法吗?