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

GraphQL share same Object type for list and detail query

我正在采用 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
}

问题是,出于某些性能原因,/users 中的 User 项的字段少于 /detail。比如address字段在listAPI中不存在,只存在detailAPI。

那么,我们是否必须为 list 查询定义另一个 UserListItem?由于后端 API 限制,我们不能在 listdetail 查询之间共享相同的 User 类型定义。

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

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

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

您可以参考这篇文章了解更多信息

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

https://kamranicus.com/posts/2018-03-06-graphql-apollo-object-caching

如果您为列表查询定义另一种类型也会导致缓存问题(关于客户端在突变后更新缓存)

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

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

如果确实不能把address字段放到列表中API,我觉得定义另一种类型比较好。

但是客户端需要多注意更新缓存的问题。


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

假设我们有一个显示用户列表的页面(类型User),并且我们有一个编辑用户信息的突变。

通常我们进入编辑页面时,会执行userDetail初始化表单数据。(type UserDetail)

如果 return 类型在突变后为 User 那么用户列表中具有相同 ID 的用户将自动更新缓存。

(https://www.apollographql.com/docs/react/advanced/caching/#automatic-cache-updates)

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

在这种情况下,我将 fetchPolicy 设置为 network-only(userDetail 查询),反之亦然。


ID 和类型相同但结果不同

参考这篇文章

https://kamranicus.com/posts/2018-03-06-graphql-apollo-object-caching