typescript - 如何在 apollo 客户端策略中使用 readField 来选择具有参数的查询
问题描述
使用@apollo/client 3.4.7
我一直在关注 Dan Reynolds 的这篇很棒的博客https://www.apollographql.com/blog/apollo-client/architecture/redux-to-apollo-data-access-patterns/解释了从 Redux 世界到 Apollo 的转变GraphQL 世界。Redux 的一个不错的部分是能够使用选择器从您的状态中选择部分数据。在 Apollo 领域,您可以运行查询,但有时您已经拥有数据并且只需要其中的一个子集。该博客详细介绍了您可以执行以下操作:
const schema: TypePoliciesSchema = {
typeDefs: gql`
extend type Query {
readManagers: [Employee!]!
}
`,
typePolicies: {
Query: {
fields: {
readManagers: {
read(employees, context) {
const employees = readField<Query, 'readEmployees'>(context, 'readEmployees');
return employees.filter(employeeRef => {
const employeeRole = readField<Employee, 'role'>(context, 'role', employeeRef);
return employeeRole === EmployeeRole.Manager;
});
},
}
}
}
}
}
这是基于一个简单的 GraphQL 查询:
query GetEmployees {
employees {
id
name
role
team
}
}
我的问题是当您的查询有参数时如何获得查询结果:
query GetEmployees($companyId: ID!) {
employees(companyId: $companyId) {
id
name
role
team
}
}
突然你不能访问 readEmployees 因为缓存键现在是这样的readEmployees({"companyId": "uuid"})
?
我很欣赏您可能还必须设置 readManagers 查询以使用参数,以获得相同的 ID 才能进行子选择。我尝试手动伪造查询键以匹配,但没有奏效。
我目前的工作是使用上下文中的缓存并运行相同的查询,并且许多将它们转换为使用 toReference 的引用:
const schema: TypePoliciesSchema = {
typeDefs: gql`
extend type Query {
readManagers: [Employee!]!
}
`,
typePolicies: {
Query: {
fields: {
readManagers: {
read(employees, context) {
const employees = context.cache.readQuery('readEmployees', { variables: { companyId: context.args.companyId || context.variables.companyId } } );
return employees.filter(employeeRef => {
const employeeRole = readField<Employee, 'role'>(context, 'role', employeeRef);
return employeeRole === EmployeeRole.Manager;
});
},
}
}
}
}
}
这感觉不是最好的解决方案,感觉就像是读取缓存的子选择的很多样板。
解决方案
根据github issue的回答,您可以使用另一种形式的readField函数,它接受对象。然后你可以在你的类型策略定义中使用它来读取带有参数的数据
users: {
read(users, { args, readField }) {
const { where: { id } } = args;
const users = readField({
fieldName: 'Users',
args: { where: { id } },
});
return users;
},
}
推荐阅读
- javascript - 试图平滑滚动动画并理解为什么我的文字会瞬间消失
- c# - 如何保存/存储和加载回编辑器窗口更改?
- javascript - 文本和字体真棒图标不会在切换时改变
- java - 我无法从我的应用程序将视频分享到 whatsapp
- python - 无法从 anaconda 中找到 python 模块,使用 pip 安装的模块
- angular - 角度叠加定位 - 它是如何工作的?
- oracle - 计算表中学生状态的触发器
- swagger - 如何为每个 HTTP 状态代码提供单独的示例?
- android - 出现此消息崩溃:java.lang.ClassCastException: com.google.firebase.Timestamp 无法转换为 java.util.Date
- java - 如何通过 2 个列表并进行检查