为什么我们需要另一个模式来进行模式拼接?

Why do we need another schema for schema stitching?

我正在阅读 blog 按域分隔 graphql 模式和解析器。

要合并解析器,这是有道理的。

import userResolver from "./User";
import messageResolver from "./Message";

export default [userResolver, messageResolver];

但是对于架构,为什么我们需要另一个架构(linkSchema)?

import { gql } from "apollo-server-express";
import userSchema from "./User";
import messageSchema from "./Message";

const linkSchema = gql`
  type Query {
    _: Boolean
  }

  type Mutation {
    _: Boolean
  }

  type Subscription {
    _: Boolean
  }
`;

export default [linkSchema, userSchema, messageSchema];

In this file, both schemas are merged with the help of a utility called linkSchema. The linkSchema defines all types shared within the schemas.

博客描述的是这样组合类型定义:

const typeDefsA = `
  type Query {
    _: Boolean
  }
`

const typeDefsB = `
  extend type Query {
    someField: String
  }
`

称此为架构拼接用词不当Schema stitching 涉及将多个独立的 GraphQL 服务组合到一个模式中。您链接的文章仅描述了构建您的项目,以便 单个模式的类型定义位于多个文件中

除此之外,我们所做的只是代表我们的模式的单个字符串,并将其拆分为多个字符串,然后我们将它们组合起来。我们也希望能够在这些类型定义中为我们的 QueryMutation 类型定义字段。但是,我们不能只这样做:

type Query {
  someField: Boolean
}

type Query {
  someOtherField: String
}

这样做会导致错误,因为我们定义了两个具有相同名称的类型。相反,我们必须使用 extend 关键字来 extend 现有类型:

type Query {
  someField: Boolean
}

# this says "add these fields to our existing type"
extend type Query {
  someOtherField: String
}

# so does this
extend type Query {
  yetAnotherField: String
}

但是,为了使用extend关键字,我们必须至少有一个类型来实际扩展。这样做也会抛出一个错误:

extend type Query {
  someField: Boolean
}

extend type Query {
  someOtherField: String
}

考虑到这一点,在拆分类型定义时,通常会有一个基本类型定义字符串来为三种操作(查询、变更和订阅)提供基本类型。然后所有其他类型定义都可以放心地扩展这些类型。这些 "base" 类型定义也是在不同文件之间共享的类型的好位置。

最后,请注意,执行此操作时也没有必要为基本操作类型提供任何字段。如果您确实在架构中的其他地方扩展了基本操作类型,您可以这样做:

type Query

extend type Query {
  someField: String
}