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

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

问题描述

在GraphQL中,一个非常普遍的用例是创建一个带有变异的对象,并接收与返回的字段完全相同的字段以及数据库返回的ID.这是一个与此相关的问题的问题.>

我的问题是,如何简化此模式以避免重复字段?我尝试将输入类型重新用作片段,

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

...但是失败了

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

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

 类型客户端{_id:字串short_name:字符串full_name:字符串地址:字符串电子邮件:字符串位置:字符串}客户端{上的ClientFields片段short_name:字符串full_name:字符串地址:字符串电子邮件:字符串位置:字符串}输入ClientInput {... ClientFields} 

有什么更好的方法吗?

解决方案

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

根据规范:

使用片段可以重复使用常见的重复选择字段,从而减少文档中的重复文本.

片段背后的目的是,您可以有任意数量的保存的查询来查询同一类型-如果架构发生更改,或者您决定不需要某个特定的查询,则不需要更新20个不同的查询.领域.

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

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

  const sharedClientFields =`short_name:字符串full_name:字符串地址:字符串电子邮件:字符串位置:字符串`const schema =`输入客户{_id:字串$ {sharedClientFields}}输入ClientInput {$ {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天全站免登陆