在 GraphQL 中重用输入类型作为片段 [英] Reusing input type as fragment in GraphQL

查看:14
本文介绍了在 GraphQL 中重用输入类型作为片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

input ClientInput {短名称:字符串full_name: 字符串地址:字符串电子邮件:字符串位置:字符串}输入客户端{id:字符串...客户端输入}

...但是失败了

<块引用>

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

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

type Client {_id:字符串短名称:字符串full_name: 字符串地址:字符串电子邮件:字符串位置:字符串}客户端上的片段 ClientFields {短名称:字符串full_name: 字符串地址:字符串电子邮件:字符串位置:字符串}输入客户端输入{...客户端字段}

那怎么更好?

解决方案

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

来自规范:

<块引用>

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

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

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

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

const sharedClientFields = `短名称:字符串full_name: 字符串地址:字符串电子邮件:字符串位置:字符串`const 架构 = `输入客户端{_id:字符串${sharedClientFields}}输入客户端输入 {${sharedClientFields}}`

A very common use case in GraphQL is creating an object with a mutation, and receiving the exact same fields back, plus and ID returned by the database. Here's a related question asking about this.

My question is, how can this pattern be simplified to avoid repeated fields? I've tried reusing the input type as a fragment,

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

type Client {
  id: String
  ...ClientInput
}

...but that failed with

Syntax Error: Expected Name, found ...

All the documentation and blog posts I've seen on Fragments always creates them on an existing type. That means still repeating all but the ID field:

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
}

How is that any better?

解决方案

TL;DR: A mechanism for allowing fields to be shared between an object type and an input object type just does not exist. Fragments can only be used client-side when composing queries.

From the specification:

Fragments allow for the reuse of common repeated selections of fields, reducing duplicated text in the document.

The intent behind fragments is that you may have any number of saved queries that query the same type -- you don't want to have to update 20 different queries if the schema changes or you decide you don't need a certain field anymore.

A similar mechanism for allowing fields to be shared between a Type and an Input Type server-side just does not exist. This is likely largely by design because even though a Type field and an Input Type field both have some kind of type, they may have other properties. For example, Input Type fields can have a default value, while that property does not exist for a Type field. Similarly, Type fields have resolvers and arguments, which Input Type fields do not.

If you really want to keep things DRY, there may be workarounds available, depending on what kind of GraphQL server you're running. If it's a GraphQL.js server that uses a schema created from one or more SDL strings, for example, you can just use template literals:

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

  type ClientInput {
    ${sharedClientFields}
  }
`

这篇关于在 GraphQL 中重用输入类型作为片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆