graphql - 能够使用相同的字段扩展所有 Apollo/GraphQL 突变。通缉“通用片段”
问题描述
问题定义
在我目前正在进行的项目中,我们使用 React 和Apollo Client。
在我们所有的突变中,我们的响应中有以下字段:
ok
errors {
field
messages
}
后端使用这些字段扩展所有突变,因此最好有一个好的、简短的方法将这些字段包含在前端的所有突变中,并且能够在未来更改这个“片段” .
因此,我有兴趣在我的所有突变中将这些相同的 4 行缩短为 1。
到目前为止我已经尝试过:
我试过研究Apollo Fragments,但是它们似乎需要字段是on
或“相关”的类型,例如。
fragment NameParts on Person {
firstName
lastName
}
在这里,framentNameParts
是使用创建的Person
。但是,我对扩展 ALL 突变很感兴趣。
如果我能像这样制作一个通用片段会很好:
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 以智能方式使用函数?
还有内联片段,但我怀疑它是否可以用于我需要的东西,而且 Apollo 中的内联片段文档很少。
本质上:有没有一种聪明的方法来扩展 Apollo 突变?通用片段是否存在?
解决方案
首先,片段不仅限于 Apollo,而且只是常规 GraphQL 查询的一部分。GraphQL 网站本身实际上对它们有很好的解释:https ://graphql.org/learn/queries/#fragments
本质上,我们可以将片段放在任何查询中以提取数据依赖关系,但它们对于使用on X
类型条件匹配类型也很有用。
在您的情况下,您是说每个突变都返回一种具有公共errors
字段的结果类型。这告诉我你可能已经有MutationError
一种类型。然而,这些MutationResult
都有errors
字段的类型都应该实现一个接口,如果他们还没有的话。
接口是模式语言中一个很好的工具,可以明确定义实现它的类型必须始终包含一组特定的字段,在这种情况下是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 中更具可预测性和预期性,而不是进行一些客户端文档转换、查询中的字符串插值或类似的事情,因为它将被纳入您的架构中。
旁注:我还要说的是,我发现人们通常已经开始将他们的突变分为“错误”和“结果”,并建立某种联合或界面来区分两者。但通常他们随后会使用消息实现一般错误。重要的是要说不携带任何关系数据的错误实际上已经融入到 GraphQL 中:https ://spec.graphql.org/June2018/#sec-Errors
推荐阅读
- javascript - 如何在画布上用矩形或圆弧模拟重力?
- jquery - 过期后从选择选项中删除日期
- c++ - Cout 无符号字符
- reactjs - 如何使用作为`* as`导入的Typescript定义
- javascript - html模式属性无法使用codeigniter form_open
- java - 安卓 BLE。如何通过原始广告数据过滤扫描
- ansible - 如何将列表转换为ansible中的列表列表
- ios - 库未加载:@rpath/FBLPromises.framework/FBLPromises iOS 13.3.1
- php - PHP 联系表 - 单个字段未填充
- c# - jquery自动完成不选择动态数据