AppSync上传Timestamp报错:Variable 'timestamp'值无效求助
问题
在通过AppSync上传时间戳时遇到阻碍,以下是测试用的Schema、Resolver配置和前端请求代码:
Schema
type Mutation { testCreateCar(input: TestCreateCarInput!): TestCar @aws_cognito_user_pools } type TestCar { regno: String! country: String! timestamp: Int } input TestCreateCarInput { regno: String! country: String! timestamp: Int }
Resolver配置
{ "version" : "2017-02-28", "operation" : "PutItem", "key" : { "regno": $util.dynamodb.toDynamoDBJson($ctx.args.regno), "country": $util.dynamodb.toDynamoDBJson($ctx.args.country), }, "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args) }
前端请求函数
export const createCar = async (carData: Car) => { try { await client.graphql({ query: mutations.testCreateCar, variables: { input: { regno: carData.regno, country: carData.country, timestamp: Date.now() } } }) } catch (err) { throw err; } };
发起请求时收到错误:"Variable 'timestamp' has an invalid value.",明明Date.now()返回的是数字,Schema也指定了timestamp为Int类型,请问问题出在哪?
解答
问题出在GraphQL的Int类型限制上:
- GraphQL标准里的Int是32位有符号整数,最大值为
2^31 - 1 = 2147483647(对应北京时间2038年1月19日)。 - 而
Date.now()返回的是13位毫秒级时间戳(比如当前时间大概是1700000000000左右),远超过32位Int的最大值,所以会被判定为无效值。
有两种解决办法:
修改Schema类型:把
timestamp的类型从Int改成Float,这样就能容纳13位毫秒时间戳,DynamoDB也支持存储Float类型的数据。
修改后的Schema片段:type TestCar { regno: String! country: String! timestamp: Float } input TestCreateCarInput { regno: String! country: String! timestamp: Float }转换为秒级时间戳:如果业务不需要毫秒精度,可以把
Date.now()除以1000并取整,得到10位秒级时间戳,这个数值在32位Int范围内(到2038年之前都可用)。
修改后的前端代码:timestamp: Math.floor(Date.now() / 1000)
如果需要毫秒精度且不想用Float,也可以把时间戳存为String类型,不过后续查询和排序时需要额外处理类型转换。
内容的提问来源于stack exchange,提问作者Gustav Vingtoft
相关产品推荐
相关产品推荐

