GraphQL为列表和详细信息查询共享相同的对象类型

GraphQL为列表和详细信息查询共享相同的对象类型,graphql,apollo,apollo-server,Graphql,Apollo,Apollo Server,我采用GraphQL作为我的数据组合层,用于几个后端微服务。我们有一个UserService,它提供一些与用户相关的RESTAPI,一个是/users,另一个是/detail?userId=${userId}。 我有以下模式定义: type User { userId: ID! name: String! address: String // ... some other fields } Query { users: [User]! userDe

我采用GraphQL作为我的数据组合层,用于几个后端微服务。我们有一个
UserService
,它提供一些与用户相关的RESTAPI,一个是
/users
,另一个是
/detail?userId=${userId}
。 我有以下模式定义:

type User {
    userId: ID!
    name: String!
    address: String
    // ... some other fields
}
Query {
    users: [User]!
    userDetail(userId: ID): User
}
问题是,出于某些性能原因,
/users
中的
User
项的字段数少于
/detail
。例如,
地址
字段不存在于列表API中,而仅存在于详细信息API中


那么,我们是否必须为列表查询定义另一个
UserListItem
?由于后端API的限制,我们不能在列表详细信息查询之间共享相同的
用户
类型定义。

首先,我想我们应该考虑一下为什么列表API中不存在地址字段

在Apollo看来,相同的用户id应该得到相同的结果。 所以在你的情况下,这是不合理的

如果不为列表查询定义其他类型,将导致缓存问题(客户端)

有关更多信息,请参阅本文

(相同id,类型不同结果)

若为列表查询定义另一种类型,也会导致缓存问题(关于变异后客户端更新缓存)

当然,客户端可以通过设置fetchPolicy或手动更新缓存来解决缓存问题,但这不是最佳解决方案

因此,如果我是后端开发人员,我将尝试将地址字段放在列表API中

如果您真的不能将地址字段放入列表API中,我认为定义另一种类型更好

但客户端需要更多地关注缓存更新问题


例如,如果我们为用户定义另一种类型。(键入
UserDetail

假设我们有一个页面来显示用户列表(type
user
),我们有一个变体来编辑用户信息

通常,当我们转到编辑页面时,我们将执行
userDetail
初始化表单数据。(键入
userDetail

如果变异后返回类型为
User
,则用户列表中具有相同id的用户将自动更新缓存

()

但是当我们回到编辑页面时,您会发现userDetail的数据在变异后保持不变,因为变异的返回类型是
User
,而不是
userDetail

在这种情况下,我将fetchPolicy设置为仅网络(userDetail query),反之亦然


id和类型相同,但结果不同

请参阅本文


谢谢您的回复。RESTAPI由其他后端开发人员管理。为什么列表API中不存在
地址
或其他一些字段,通常与性能有关。可能所有的
User
数据都被分成两个数据库表:一个表只保存一些简短的数据,另一个表包含更多的用户详细信息。通过将用户数据分成两个表,我们可以更快地读取和写入MySQL。当我们需要显示用户列表时,我们只需要从一个表中选择,而不需要加入另一个详细表。@Jess我了解您的情况,我更新了我的答案,描述了客户端可能遇到的问题。我不知道什么是最好的解决方案,所以我只是分享我的经验。对不起,我的英语很差,希望你能理解我想表达的意思。再次感谢你的经验。我从你的回答中学到了很多。顺便说一句,我认为你的英语很好