在 GraphQL 中重用输入类型作为片段

Dan*_*scu 4 types graphql

GraphQL 中一个非常常见的用例是创建一个带有突变的对象,并接收完全相同的字段、数据库返回的加号和 ID。这是一个相关的问题,询问这个。

我的问题是,如何简化这种模式以避免重复字段?我试过将输入类型重用为片段,

input ClientInput {
  short_name: String
  full_name: String
  address: String
  email: String
  location: String  
}

type Client {
  id: String
  ...ClientInput
}
Run Code Online (Sandbox Code Playgroud)

...但失败了

语法错误:预期名称,找到...

我在 Fragments 上看到的所有文档和博客文章总是将它们创建on为现有类型。这意味着仍然重复除 ID 字段之外的所有内容:

type Client {
  _id: String
  short_name: String
  full_name: String
  address: String
  email: String
  location: String
}

fragment ClientFields on Client {
  short_name: String
  full_name: String
  address: String
  email: String
  location: String
}

input ClientInput {
  ...ClientFields
}
Run Code Online (Sandbox Code Playgroud)

怎么样更好?

Dan*_*den 7

TL;DR:不存在允许在对象类型和输入对象类型之间共享字段的机制。在编写查询时,片段只能在客户端使用。

从规范:

片段允许重复使用常见的重复字段选择,减少文档中的重复文本。

片段背后的意图是,您可能拥有任意数量的查询相同类型的已保存查询——如果架构更改或您决定不再需要某个字段,您不希望必须更新 20 个不同的查询。

允许字段在类型和输入类型服务器端之间共享的类似机制不存在。这可能主要是设计使然,因为即使 Type 字段和 Input Type 字段都具有某种type,但它们可能具有其他属性。例如,输入类型字段可以具有默认值,而类型字段不存在该属性。类似地,类型字段具有解析器和参数,而输入类型字段则没有。

如果您真的想让事情保持干燥,那么可能有可用的解决方法,具体取决于您正在运行的 GraphQL 服务器类型。例如,如果它是使用从一个或多个 SDL 字符串创建的架构的 GraphQL.js 服务器,则可以只使用模板文字:

const sharedClientFields = `
    short_name: String
    full_name: String
    address: String
    email: String
    location: String 
`
const schema = `
  type Client {
    _id: String
    ${sharedClientFields}
  }

  type ClientInput {
    ${sharedClientFields}
  }
`
Run Code Online (Sandbox Code Playgroud)