发布于 2026-01-06 4 阅读
0

GraphQL 新手教程 - 模式定义

GraphQL 新手教程 - 模式定义

这篇博文是新手教程的一部分。关注我,获取更多内容。

在上一篇关于 GraphQL 的文章中,我们已经对 GraphQL 进行了理论介绍。接下来,我们将介绍该标准的一个重要组成部分——类型系统。类型系统允许您定义 API 模式,即 GraphQL 模式定义语言 (SDL)。SDL 是一种特殊的语法,它拥有非常完善的文档,并且其设计使得无论使用何种语言或框架,您都可以使用它。

类型系统

GraphQL 是强类型的,这意味着每个定义都必须具有特定的类型。类型系统为此提供了帮助,它为定义 API 元素提供了多种可能性。让我们以图书馆应用(书籍和作者)为例,声明 API 的初始类型。点击图片查看书籍示例。

整个问题中最重要且最常用的元素是对象类型,简单来说,它就是一组字段的集合。以上示例:两个对象分别使用 `type Book {}` 和 `type Author {}` 定义声明,而这些声明内部包含特定类型的字段,例如 `name: String!` 和 `isBookOftheYear: Boolean!`。

标量类型

GraphQL 中有几种内置的标量类型用于字段声明:

  • 字符串 - 以 UTF-8 格式表示的字符集,
  • Int - 32 位整数,
  • 浮点数(Float)
  • 布尔值 - 真或假
  • ID——一种表示对象唯一标识符的类型,最常用于重新下载(由缓存使用)。它的序列化方式与字符串类型相同。

界面

GraphQL 的类型系统以接口为核心。接口公开了一组特定的字段,实现该接口的类型必须包含这些字段。例如,我们可以用 Publication 接口来表示书籍或杂志。这些类型具有一些共同的特征,例如标题和发行日期。

作者很可能既可以出版书籍也可以出版杂志,因为借助该界面,您无需依赖于特定的出版类型,在这种情况下,我们可以使用更大规模的抽象概念,即“出版”。

联盟

联合类型是一种有趣的机制,它允许你表示一组不具有相同字段的对象。一个很好的例子是向搜索引擎发出查询,该查询可以同时搜索书名和作者姓名。通过以下声明,你可以发出类似这样的查询:

union SearchResult = Book | Author

type Query {
  search(text: String!): SearchResult
}

query {
  search(text: "Park") {
    ... on Book {
      title
    }
    ... on Author {
      name
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

因此,我们将看到答案:

    {
      "data": {
        "search": [
          {
            "name": "Jurassic Park",
          },
          {
            "name": "Jessica Park",
          }
        ]
      }
    }
Enter fullscreen mode Exit fullscreen mode

在可视化编辑器中查看效果:

声明方案

定义 API 方案时,可以使用两个顶级元素——查询 (query) 和变更 (mutation),它们是与其他对象创建方式相同的普通对象。我们在其中声明 API 的功能。方案本身的定义非常简单:

schema {
  query: Query
  mutation: Mutation
}

type Query {
}

type Mutation {
}
Enter fullscreen mode Exit fullscreen mode

询问

查询是模式中的必需元素,负责读取 API。此对象中定义的所有字段都可以与各种 API 端点进行比较。公认的原则是,通过查询发出的元素是名词,明确指定要下载的实体——在上面的示例中,它们是“书”和“作者”。为了更好地说明整体,您可以将之前对对象的定义移到查询中。

schema {
  query: Query
}

type Query {
  book(id: ID!): Book
  author(id: ID!): Author
}

type Book {
  id: ID!
  title: String!
  shortDescription: String!
  description: String
  pages: Int!
  isbn: String!
  releaseDate: String!
  isBookOftheYear: Boolean!
  author: Author!
}

type Author {
  id: ID!
  name: String!
  bio: String
  sex: String!
  books: [Book!]!
}
Enter fullscreen mode Exit fullscreen mode

论点

在某些代码行中,您可以看到字段声明与之前的示例略有不同(例如 `book (id: String!)`)。除了字段名称之外,您还可以看到带有另一项声明的括号——这实际上就是为查询添加一个参数——您可以根据该参数传递一些要下载的数据。在上面的示例中,需要用户的 ID,执行的查询如下所示:

query {
  book(id: "1234") {
    title
    isbn
  }
}
Enter fullscreen mode Exit fullscreen mode

突变

变更(Mutation)是一个可选组件,允许您通过 API 在我们的应用程序中添加、编辑或删除项目。它的定义与查询(Query)类型相同。唯一的区别在于定义字段的原则——与查询不同,变更中的字段通常被称为动词,它们明确地定义了要执行的操作。除了上述示例之外,还值得一提的是创建新书籍的功能。

输入类型

在介绍 mutation 声明示例之前,值得一提的是,在类型系统部分讨论所有基本类型时,还有一种类型被忽略了。为了通过 GraphQL 修改或创建新元素,我们创建了一种特殊的 input 类型。它的行为与普通对象非常相似,区别在于声明时使用的是 input 而不是 type 关键字。

schema {
  query: Query
  mutation: Mutation
}

type Mutation {
  createAuthor(input: AuthorInput): Author
  updateAuthor(id: ID!, input: AuthorInput): Author
}

input AuthorInput {
  name: String!
  bio: String
  sex: String!
}
Enter fullscreen mode Exit fullscreen mode

在上面的示例中,您可以看到 createAuthor 和 updateAuthor 操作需要 AuthorInput 对象作为参数,并返回 Author 对象。对于声明的方案,创建新书需要类似的操作:

mutation {
  createAuthor(input: {
    name: String!
    bio: String
    sex: String!
  }) {
    id
    title
  }
}
Enter fullscreen mode Exit fullscreen mode

如果您正在寻找最佳的GraphQL教程,请查看这篇文章

文章来源:https://dev.to/iamrobert/graphql-tutorial-for-newbies---schema-definition-7dm