我将GraphQL用作几个后端微服务的数据组合层。我们有一个UserService
,它提供了一些与用户相关的REST API,一个是/users
,另一个是/detail?userId=${userId}
。
我有以下架构定义:
type User {
userId: ID!
name: String!
address: String
// ... some other fields
}
Query {
users: [User]!
userDetail(userId: ID): User
}
问题是由于某种性能原因,User
中的/users
项目的字段少于/detail
。例如,address
字段在 list API中不存在,而仅在 detail API中存在。
因此,我们是否需要为 list 查询定义另一个UserListItem
?由于后端API的限制,我们不能在 list 和 details 查询之间共享相同的User
类型定义。
答案 0 :(得分:0)
首先,我认为我们应该考虑为什么列表API中不存在地址字段?
在Apollo看来,相同的用户ID应该得到相同的结果。 因此,根据您的情况,这是不合理的。
如果您没有为列表查询定义其他类型,则会导致缓存问题(客户端)
您可以参考本文以获取更多信息
(相同的ID,键入不同的结果)
https://kamranicus.com/posts/2018-03-06-graphql-apollo-object-caching
如果您为列表查询定义其他类型,也会导致缓存问题(关于客户端在突变后更新缓存)
当然,客户端可以通过设置fetchPolicy或手动更新缓存来解决缓存问题,但这不是最佳解决方案。
因此,如果我是后端开发人员,我将尝试将地址字段放入列表API。
如果您确实不能在列表API中放置地址字段,我认为定义另一种类型更好。
但是客户端需要更加注意更新缓存问题。
例如,如果我们为用户定义了另一种类型。 (类型UserDetail
)
假设我们有一个页面来显示用户列表(类型User
),并且我们有一个变体来编辑用户信息。
通常,当我们进入编辑页面时,我们将执行userDetail
来初始化表单数据。(类型UserDetail
)
如果突变后返回类型为User
,则用户列表中具有相同ID的用户将自动更新缓存。
(https://www.apollographql.com/docs/react/advanced/caching/#automatic-cache-updates)
但是,当我们返回到编辑页面时,您会发现突变后的userDetail数据保持不变,因为突变的返回类型为User
而不是UserDetail
。
在这种情况下,我将fetchPolicy设置为network-only
(userDetail查询),反之亦然。
相同的ID和类型,但结果不同
请参阅本文
https://kamranicus.com/posts/2018-03-06-graphql-apollo-object-caching