GraphQL(二)- Schema 和 Resolver

在GraphQL中,Schema和Resolver是两个非常重要的概念,是编写GraphQL Server的2个基本单元
本文介绍GraphQL中的Schema和Resolver。

Schema

Schema定义了GraphQL中基于graph的数据格式
参考: https://graphql.org/learn/schema/

Type语言

GraphQL 服务可以用任何语言编写。由于我们不能依赖特定的编程语言语法(如 JavaScript)来讨论 GraphQL 模式,因此我们将定义自己的简单语言。我们将使用“GraphQL 模式语言”:它类似于查询语言,并允许我们以与语言无关的方式讨论 GraphQL 模式。

如用type定义一个对象:

type Book {
    title: String!
    author: String!
    price: Float
    year: Int
}

类型后加!代表这个属性是对象必不可少(Non-Nullable)的,否则是optional的

在object定义中,Query,Mutation和Subscription是不可用做类名的,而typedef这3者则定义了该schema中的Query,Mutaion和Subscription。

Scalar类型

GraphQL提供了5种基本数据类型,分别为:

  • String UTF‐8 字符序列。
  • Int 有符号的 32 位整数。
  • Float 有符号的双精度浮点值。
  • Boolean true/false
  • ID ID 标量类型表示唯一标识符,通常用于重新获取对象或作为缓存的键。ID 类型的序列化方式与字符串相同,但是,将其定义为ID表示它不是可读的。

Enum

type中枚举类型的定义:

enum Days_of_Week{
   SUNDAY
   MONDAY
   TUESDAY
   WEDNESDAY
   THURSDAY
   FRIDAY
   SATURDAY
}

注意数据传递后,枚举类型的内容会变成与枚举变量名字相同的String而不是Int

Array

Schema支持数组,经过数组可以批量Query数据,resolver也可以处理数组中的数据过滤等操作

type Character {
  name: String!
  appearsIn: [Episode]!
}

下面显示!分别定义在数组和数据类型之后的差别:

myField: [String!]

myField: null // valid
myField: [] // valid
myField: ['a', 'b'] // valid
myField: ['a', null, 'b'] // error`

myField: [String]!

myField: null // error
myField: [] // valid
myField: ['a', 'b'] // valid
myField: ['a', null, 'b'] // valid

Interface

和其它语言的面向对象概念一样,graphql也引入了继承的概念,
Interface作为一种抽象类型存在,想要使用必须由实体的type继承。

interface Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
}

type Human implements Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
  starships: [Starship]
  totalCredits: Int
}

type Droid implements Character {
  id: ID!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
  primaryFunction: String
}

Union

Schema中也支持Union类型作为多种类型的Union使用

union SearchResult = Human | Droid | Starship

Input

到目前为止,我们只讨论了将Scalar(如枚举或字符串)作为参数传递到字段中。但您也可以轻松传递复杂对象。这在突变的情况下特别有价值,因为您可能希望传入要创建的整个对象。在 GraphQL 模式语言中,输入类型看起来与常规对象类型完全相同,但使用关键字input

input ReviewInput {
  stars: Int!
  commentary: String
}
mutation CreateReviewForEpisode($review: ReviewInput!) {
  createReview(review: $review) {
    stars
    commentary
  }
}

Resolver

Resolver是为 GraphQL 查询生成响应的函数集合。简单来说,Resolver充当 GraphQL 查询处理程序。

参数

GraphQL 模式中的每个Resolver函数都接受四个位置参数,如下所示 -

fieldName:(root, args, context, info) => { result }

Resolver函数的示例如下所示 -

//resolver function with no parameters and returning string
greeting:() => {
   return "hello from TutorialsPoint !!!"
}

//resolver function with no parameters and returning list
students:() => db.students.list()

//resolver function with arguments and returning object
studentById:(root,args,context,info) => {
   return db.students.get(args.id);
}

下面给出的是参数及其描述 -

  • root 包含从父字段上的解析程序返回的结果的对象。
  • args 一个对象,其中包含传递到查询中的字段的参数。
  • context 这是特定查询中所有解析程序共享的对象。
  • info 它包含有关查询的执行状态的信息,包括字段名称、从根到字段的路径。

Data Source

数据源是 Apollo Server 可用于封装从特定源(如数据库或 REST API)获取数据的类。这些类有助于在解决操作时处理缓存、重复数据删除和错误。

您的服务器可以使用任意数量的不同数据源。不必使用数据源来提取数据,但强烈建议使用它们。

image

Error Handling

当Query或者Mutation操作出现问题时,一般GraphQL会返回一个Error的Json信息,如:

{
  "errors":[
    {
      "message":"Cannot query field \"__typenam\" on type \"Query\".",
      "locations":[
        {
          "line":1,
          "column":2
        }
      ],
      "extensions":{
        "code":"GRAPHQL_VALIDATION_FAILED",
        "exception":{
          "stacktrace":[
            "GraphQLError: Cannot query field \"__typenam\" on type \"Query\".",
            "    at Object.Field (/my_project/node_modules/graphql/validation/rules/FieldsOnCorrectTypeRule.js:48:31)",
            "    ...additional lines...",
          ]
        }
      }
    }
  ]
}

错误信息可以是GraphQL自带Error类型或是我们在Resolver中throw,默认的错误类型有:

image

参考:https://www.apollographql.com/docs/apollo-server/v3/data/errors

posted @ 2023-01-16 16:00  Asp1rant  阅读(526)  评论(0编辑  收藏  举报