Graphql ID 解析为字符串,即使它是整数

Posted

技术标签:

【中文标题】Graphql ID 解析为字符串,即使它是整数【英文标题】:Graphql ID resolves as string even if it's integer 【发布时间】:2020-05-11 04:21:36 【问题描述】:

我是 graphql 的新手,希望有人能给我解释一下这种始终为字符串的 ID 类型。

正如文档中的悲伤:

ID 标量类型表示唯一标识符,通常用于重新获取对象或作为缓存的键。

如果你使用,例如,像 Apollo 这样的缓存客户端,每种类型 应该至少有一个 ID。这允许我们执行标准化 查询,使我们能够更新 Apollo 中的内容 内部 redux 存储自动基于唯一 id

好的,所以我可以使用 int,但是我如何在客户端将我的 id 作为整数?

原因很简单,假设我有 Book 类型,其 id 为 ID 类型,author_id 关系为 Int 类型。我也有 ID 类型为 ID 的 Author 类型。在我获取书籍和作者之后,我将拥有 book.author_id int 和 author.id 字符串,但它是相同的数字!

我该怎么办?即使是多对多关系也使用无处不在的 ID?创建新的标量 ID 类型,可用作重新获取的 ID,但类型为 Int?

【问题讨论】:

这似乎不是来自任何官方文档,只是一些文章。还有一个旧的,因为 Apollo 客户端从 2.0 版开始就没有使用过 redux。 【参考方案1】:

在 apollo 中,您可以使用 typePolicies 来确定将哪个字段用作唯一标识符。这将解决身份证的痛苦!类型转换为字符串。

const typePolicies = 
  Book: 
    keyFields: ['id'],
  ,  
  BookTag: 
    keyFields: ['book_id', 'tag_id'],
  


  return new ApolloClient(
    cache: new InMemoryCache( typePolicies ),
  )

【讨论】:

【参考方案2】:

来自spec:

ID类型的序列化方式与String相同;但是,它并不适合人类阅读。虽然它通常是数字,但它应该始终序列化为字符串...... GraphQL 与 ID 格式无关,并且序列化为字符串以确保 ID 可以表示的许多格式的一致性,从小的自动增量数字到大的 128 位随机数数字、base64 编码值或 GUID 等格式的字符串值。

目前尚不清楚为什么客户端会关心在这种情况下比较 ID - 无论如何,像 author_id 这样的列通常应该对客户端隐藏,架构只公开相关实体,而不是仅用于链接实体的字段.也就是说,ID 只是一个 ID,客户端不应该关心它是字符串还是整数,只要它是一致的。如果你有一个字段返回一个整数 (Book.author_id) 而另一个返回一个字符串 (Author.id),那么这是你的架构的一个问题。

ID 标量可用于任意数量的字段,而不仅仅是一个字段(可能命名为id,也可能不命名)。同样,如果你想使用 Int 或 String 作为 id 字段的类型,你可以——这不会影响 Apollo 缓存结果的能力。

【讨论】:

隐藏是什么意思? Id 是客户端组件渲染和比较的前 1 个道具。 一本书应该有一个id字段,但通常没有理由公开一个author_id字段。它应该只公开一个返回作者对象的author 字段。 author_id 是一个实现细节——它与服务器相关,因为这是您加载相关实体的方式,但它可能与客户端无关。 @RTW 重读您的问题,我意识到您可能一直在询问 ID 标量在用作 输入 之类的参数时如何解析 .如果是这种情况,请记住,如果您的数据库驱动程序/查询构建器/ORM 需要一个整数作为参数,并且由于您使用了 ID 标量,您在解析器中获得了一个字符串参数,您可以随时调用 @987654329 @.

以上是关于Graphql ID 解析为字符串,即使它是整数的主要内容,如果未能解决你的问题,请参考以下文章

在 Graphql 中解析类型

Graphql查询只解析_id字段,其他字段为空

GraphQL 解析器,用于按名称而不是 ID 获取项目

联合内的 GraphQL 联合

GraphQL 关系泄漏数据,即使已经设置了 context.user 解析器。如何防止通过关系暴露数据?

在graphql中为用户类型中的字段编写字段级解析器