了解 GraphQL 与 Schema 定义的龃龉

GraphQL 是一种用于 API 的查询语言,其语法类似于 JSON,旨在提升 API 的灵活性和可扩展性。然而,在使用 GraphQL 时,我们往往会遇到一些与 Schema 定义相关的问题,这些问题可能会对我们的项目产生深远的影响。

Schema 的概念

首先,我们需要明确 Schema 的概念。在 GraphQL 中,Schema 定义了我们的 API 的类型、查询和变化之间的关系,它是我们定义的源头和唯一实例标准。我们定义的每一种类型都有自己的名称和字段,这些字段可以分成标量类型和自定义类型两类。

示例代码

为了更好地说明问题,让我们看一个示例代码。假设我们有一个 getUserById 的查询,用于按照用户的 id 查询用户信息。我们的类型定义如下:

type User {
  id: ID!
  name: String!
  email: String!
}
type Query {
  getUserById(id: ID!): User
}

在如上例子中,我们定义了 User 类型和 Query 类型,其中 User 类型有三个字段,分别是 id、name 和 email,Query 类型定义了一个名为 getUserById 的查询,并接受一个 id 参数。

问题的出现

然而,问题就在于,当我们的 API 开始变得复杂起来之后,我们定义的 Schema 显然会变得十分臃肿。例如,我们需要定义一个 getPostsByUserId 的查询,用于获取某个用户的所有帖子。此时,我们可能会定义一个名为 Post 的类型,并与 User 类型之间建立关联:

type User {
  id: ID!
  name: String!
  email: String!
  posts: [Post!]!
}
type Post {
  id: ID!
  title: String!
  content: String!
  author: User!
}
type Query {
  getUserById(id: ID!): User
  getPostsByUserId(userId: ID!): [Post!]!
}

这种方式看起来很麻烦,因为我们需要在定义每个类型时手动指定它们的关系。此外,如果我们不小心漏掉了一个关联,就会导致代码出现问题,这将比较难以排查。

解决方案

为了解决这个问题,我们可以引入另一种类型的定义方式,即 Interface 和 Union。这些定义方式可以帮助我们更好地建立对象之间的关系,从而更容易地定义我们的 Schema 。我们将上面的示例代码作出如下改动:

interface Node {
  id: ID!
}
type User implements Node {
  id: ID!
  name: String!
  email: String!
  posts: [Post!]!
}
type Post implements Node {
  id: ID!
  title: String!
  content: String!
  author: User!
}
type Query {
  node(id: ID!): Node
}

在上述示例中,我们定义了一个 Node 接口,它告诉 GraphQL 我们希望 User 和 Post 这两种类型都要实现 id 字段。此外,我们将 getUserById 和 getPostsByUserId 合并为 node,这样我们就可以使用单个查询获取它们的所有信息。

总结

在使用 GraphQL 的过程中,Schema 的定义是一项非常重要的工作。通过合理的接口和联合定义,我们可以更容易地维护和扩展代码,同时也能够更清晰地了解各个类型之间的关系。相信本文对于有意使用 GraphQL 的前端工程师而言,有一定的启发和指导意义。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6590e570eb4cecbf2d628bf1


纠错
反馈