能够使用相同的字段扩展所有 Apollo/GraphQL 突变。通缉“通用片段”

Posted

技术标签:

【中文标题】能够使用相同的字段扩展所有 Apollo/GraphQL 突变。通缉“通用片段”【英文标题】:Ability to extend all Apollo/GraphQL mutations with same fields. "Generic fragments" wanted 【发布时间】:2021-08-08 14:43:17 【问题描述】:

问题定义

在我目前正在进行的项目中,我们正在使用带有Apollo Client 的 React。

对于我们所有的突变,我们的响应中有以下字段:

ok
errors 
  field
  messages

后端使用这些字段扩展所有突变,因此最好有一个好的、简短的方法将这些字段包含在前端的所有突变中,并且能够更改这个“片段”未来。

因此,我有兴趣在我的所有突变中将这 4 行缩短为 1 行。

到目前为止我尝试过的:

我已尝试查看 Apollo fragments,但它们似乎需要字段为 on 或“相关”的类型,例如。

fragment NameParts on Person 
  firstName
  lastName

在这里,框架NameParts 是使用Person 创建的。不过,我对扩展所有突变很感兴趣。

如果我能像这样制作一个通用片段,那就太好了:

fragment OkAndErrors 
  ok
  errors 
    field
    messages
  

这似乎是不可能的。

我也尝试过制作一个字符串,并将其导入到我的突变中,如下所示:

export const OK_AND_ERRORS: string = `
  ok
  errors 
    field
    messages
  
`;
import  gql  from "apollo-boost";
import  OK_AND_ERRORS  from "./OK_AND_ERRORS";

export const CREATE_API = gql`
  mutation CreateApi($newApi: ApiCreateGenericType!) 
    createDrugapi(newDrugapi: $newDrugapi) 
      $OK_AND_ERRORS
      (...rest of mutation is omitted for brevity)
    
  
`;

再次,它没有工作。

我不确定是否可以将gql 函数巧妙地用于字符串或 JSON?

还有inline fragments,但我怀疑它是否可以用于我需要的东西,而且 Apollo 中关于 inline-fragments 的文档很少。

本质上:是否有扩展 Apollo 突变的聪明方法?通用片段是否存在?

【问题讨论】:

聪明吗?我在某个地方(在 SO 上?)看到该链接可用于删除变量中的所有 __typename 道具以进行突变...您可以尝试使用链接将您的字段添加到突变中的查询道具(AST) 你所说的“on SO”是什么意思? “链接”是什么意思? Apollo 文档references a way to link 这就是您所指的吗?如果你能提供一个你读过的文章的链接,那就太好了:-) 我希望我的问题和问题是可以理解的。 是的,apollo links ...订阅配置将订阅查询定向到套接字链接apollographql.com/docs/react/data/subscriptions/… ...删除类型名?不难找到***.com/a/51380645/6124657 不知道 Apollo 有中间件 - 完美!非常感谢!我会尝试一下,我会很快发布我的问题的答案:) 嗨彼得@PeterOeClausen 看来我面临着和你一样的需求,你终于解决了你的问题吗?我想听听你更新的任何好消息,你能分享你的方法吗?提前致谢 【参考方案1】:

首先,片段不仅限于 Apollo,而且只是常规 GraphQL 查询的一部分。 GraphQL 网站本身实际上对它们有很好的解释:https://graphql.org/learn/queries/#fragments

基本上,我们可以将片段放到任何查询中以提取数据依赖关系,但它们对于使用 on X 类型条件匹配类型也很有用。

在您的情况下,您是说每个突变都返回一种具有公共 errors 字段的结果类型。这告诉我你可能已经有了MutationError 类型。但是,这些都具有errors 字段的MutationResult 类型都应该实现一个接口,如果它们还没有的话。

接口是模式语言中一个很好的工具,可以明确定义实现它的类型必须始终包含一组特定字段,在本例中为 errors 字段。这意味着我们会这样写我们的结果:

interface MutationResult 
  errors: [MutationError!]


type ExampleMutationResult implements MutationResult 
  ok: Boolean
  errors: [MutationError!]


type UserMutationResult implements MutationResult 
  user: User
  errors: [MutationError!]

正如您在上面看到的,MutationResult 接口现在由多个结果实现,这使我可以编写一个可重用的片段,该片段可以应用于任何实现它的类型,例如

fragment MutationResultErrors on MutationResult 
  errors 
    field
    messages
  

然后我可以开始将其用于我定义的所有突变查询。这在 GraphQL 中更具可预测性和预期性,而不是进行一些客户端文档转换、查询中的字符串插值或类似的事情,因为它将被纳入您的架构中。

旁注:我还要说的是,我发现人们已经开始将他们的突变分为“错误”和“结果”并做出某种union 或 interface 来区分两者。但通常他们随后会使用消息实现一般错误。重要的是,不携带任何关系数据的错误实际上已经被嵌入到 GraphQL 中:https://spec.graphql.org/June2018/#sec-Errors

【讨论】:

以上是关于能够使用相同的字段扩展所有 Apollo/GraphQL 突变。通缉“通用片段”的主要内容,如果未能解决你的问题,请参考以下文章

Django:如何将相同的功能扩展到多个视图?

使用单个侦听器多次调用 DatePicker

发布具有相同名称属性的表单字段

如何使用 django 查询检查数据库字段的所有值是不是相同

excel如何统计某个字段内所有出现的字段的次数

可使用文本字段扩展的 Tableview 单元格会导致文本字段跳来跳去