尽管有数据,但GraphQL查询上的日期字段返回为空

时间:2019-10-30 09:45:31

标签: node.js graphql typeorm

我在将一些数据从PostgreSQL数据库传输到服务时遇到问题。

设置方式如下:

Service1将GraphQL请求发送到Service2询问数据。 Service2将此数据存储在PostgreSQL数据库中,并从该数据库中获取信息。

使用TypeORM和GraphQL的装饰器将数据建模为实体。我遇到问题的确切字段是这样的:

   @Column({
        nullable: true,
        type: 'timestamp'
    })
    @Field(() => GraphQLISODateTime, {nullable: true})
    executed_on: Date

当数据从数据库到达service2时,它存在,所有字段都在那里,并且date字段及其值也存在。

从数据库中获取时的字段:

"executed_on": "2019-10-27T23:00:00.000Z"

从Service1提取的字段:

"executed_on": null

当将其发送到service1时,我可以进行console.log记录数据,然后看到那里的字段。我假设由于GraphQL以JSON格式发送数据,因此date字段成为字符串。现在,当此数据从service1传输到其他位置时,所有executed_on字段值都为空。我不知道发生这种情况的原因。可能是因为它现在是一个字符串,所以它没有被解析为Date字段?

我发现一种解决方法是循环访问数组中的每个对象,并仅根据当前的字符串值创建一个新的Date对象,但这不是我想要做的事情,因为当我在其他服务中也会发生此过程是从外部REST API提取数据的,所以我猜这将是一个糟糕的设计?我对此很陌生。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我面临类似的问题,我认为这是由于GraphQl节点模块中DateTime类型的序列化错误所致。

这是失败的原因:

// node_modules/graphql/execution/execute.js:
completeLeafValue(returnType, result) {
  // this returns null even though a correct "value" is being passed in
  var serializedResult = returnType.serialize(result);
  ...

因为它的序列化器由于“ value instanceof Date”而失败,并且只返回null:

serialize(value) {
  return value instanceof Date ? value.toISOString() : null;
}

由于某种原因,type = Date被强制转换为“ DateTime”,为什么我还没有弄清楚,但在我看来,它应该抛出一个错误而不是仅仅返回null。

您已经说过:唯一的解决方法/修复是为对象树中的每个Date字段创建一个新的Date(...)对象。

或者分叉原始存储库,并将此代码添加到“ completeLeafValue”方法中:

//node_modules/graphql/execution/execute.js:
completeLeafValue(returnType, result) {
  var serializedResult = returnType.serialize(result);
  if(completeLeafValue==="DateTime") {
    result = new Date(result);
    //new Date(...) does not throw and only returns null when it fails
    //so we have to check for null
    if(result === null) { 
      throw new Error(`Cannot cast ${result} to Date object`);
    }
  }
  ...(rest or original fn)