调查了GraphQL的Scaler中Int类型为32位的原因的故事
本文是Supership集团2021年Advent Calendar第14天的文章。
首先
Int标量类型表示一个带符号的32位数值,不包含小数。支持32位整数或数字类型的响应格式应使用该类型来表示此标量。
GraphQL中的Int类型被定义为32位,而对于现代来说,为什么它能处理的数字范围较小,这是我感到好奇并进行了调查的原因。
GraphQL规范
它没有包含在内,因为它在所有平台上都不可用,尤其是在我们的情况下:JavaScript。
根据早前的 GraphQL 规范问题,有评论指出该功能在所有平台(JavaScript)上都无法使用。
JavaScript中的Number
檢証環境是Chrome的版本為96.0.4664.93。
在 JavaScript 中,Number 类型定义了一个称为 Number.MAX_SAFE_INTEGER 的安全整数的上限。JavaScript 中的 Number 类型采用 IEEE754 标准,因此会涉及到其精度的讨论。
Number.MAX_SAFE_INTEGER // 9007199254740991
如何确保安全操作?
这是使用大于Number.MAX_SAFE_INTEGER的值进行比较的示例。
9007199254740992 === 9007199254740993 // true
在这种情况下,由于数字不同,看起来应该返回false才是正确的,但由于被四舍五入了,结果却变成了true。
如果GraphQL API返回一个大于Number.MAX_SAFE_INTEGER的值,会发生什么?
如果后端使用GraphQL而前端使用React或Vue等JavaScript框架来构建Web应用程序,那么需要使用类似Apollo Client的GraphQL客户端从API获取值并使用。在这种情况下,需要使用JSON.parse将返回的JSON字符串转换为JavaScript对象来操作HTTP响应体中的数据。
JSON.parse(`{"value": 90071992547409918712}`) // {value: 90071992547409920000}
当JSON.parse在有超过Number.MAX_SAFE_INTEGER的值时,原本的数值为90071992547409918712,但结果变成了90071992547409920000,导致数值发生了变化。
使用这个 JavaScript 对象可能会导致使用与 API 返回值不同的数值,因此需要注意。
总结
如果处理超过 Number.MAX_SAFE_INTEGER 的整数时,需要注意以下事项。
-
- 該当するGraphQLのフィールドのScalerをIntからStringに変更する
- JavaScriptで比較や演算する場合はBigIntを使う
最后
Supership热情地招募参与产品开发和服务开发的人员。
如果您有兴趣,请点击下面的链接查看详情。
Supership集团招聘网站。
非常感谢您的关注。