环回 4 中数据模型的嵌套对象反序列化异常

Exception in deserialization of nested objects for datamodels in loopback 4

在一个非常小的 loopback4 项目中,我们尝试生成这样的嵌套实体:

import {Entity, model, property} from '@loopback/repository';

@model()
export class MySubEntity extends Entity {
  @property({
    type: 'string',
  })
  mySubEntityName?: string;

  constructor(data?: Partial<MySubEntity>) {
    super(data);
  }
}

@model()
export class MyMainEntity extends Entity {
  @property({
    type: 'string',
    id: true,
  })
  id?: string;

  @property({
    type: MySubEntity,
  })
  subEntity?: MySubEntity;

  constructor(data?: Partial<MyMainEntity>) {
    super(data);
  }
}

创建以下结构(也在文档数据库中):

{
  "id": "uuid123213",
  "subEntity": {
    "mySubEntityName": "Hello test"
  }
}

使用此控制器:

  @post('/myMainEntity', {
    responses: {
      '200': {
        content: { 'application/json': { 'x-ts-type': MyMainEntity } },
      },
    },
  })
  async create(@requestBody() myMainEntity: MyMainEntity): Promise<MyMainEntity> {
    return await this.myMainEntityRepository.create(myMainEntity);
  }

Loopback4 编译并启动应用程序。不幸的是,当我们尝试创建这个对象时,我们得到以下异常:

Unhandled error in POST /myMainEntity: 500 TypeError: Class constructor MySubEntity cannot be invoked without 'new'
    at MyMainEntity.set [as subEntity] (C:\projectOne\myMainEntity-ms\node_modules\loopback-datasource-juggler\lib\model-builder.js:598:81)
    at MyMainEntity.ModelBaseClass._initProperties (C:\projectOne\myMainEntity-ms\node_modules\loopback-datasource-juggler\lib\model.js:204:17)
    at MyMainEntity.ModelBaseClass (C:\projectOne\myMainEntity-ms\node_modules\loopback-datasource-juggler\lib\model.js:62:8)
    at new MyMainEntity (eval at createModelClassCtor (C:\projectOne\myMainEntity-ms\node_modules\loopback-datasource-juggler\lib\model-builder.js:671:21), <anonymous>:12:24)
    at Function.DataAccessObject.create (C:\projectOne\myMainEntity-ms\node_modules\loopback-datasource-juggler\lib\dao.js:331:13)
    at MyMainEntitysDataSource.onConnected (C:\projectOne\myMainEntity-ms\node_modules\loopback-datasource-juggler\lib\datasource.js:2524:14)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:106:13)
    at MyMainEntitysDataSource.emit (events.js:208:7)
    at C:\projectOne\myMainEntity-ms\node_modules\loopback-datasource-juggler\lib\datasource.js:323:12
    at C:\projectOne\myMainEntity-ms\node_modules\loopback-connector-mongodb\lib\mongodb.js:310:25
    at parseHandler (C:\projectOne\myMainEntity-ms\node_modules\mongodb\lib\url_parser.js:134:38)
    at module.exports (C:\projectOne\myMainEntity-ms\node_modules\mongodb\lib\url_parser.js:25:12)
    at C:\projectOne\myMainEntity-ms\node_modules\loopback-connector-mongodb\lib\mongodb.js:305:16
    at result (C:\projectOne\myMainEntity-ms\node_modules\mongodb\lib\utils.js:414:17)
    at executeCallback (C:\projectOne\myMainEntity-ms\node_modules\mongodb\lib\utils.js:406:9)

有人知道我在这里做错了什么吗?是否有不同的可能性来获得键入的嵌套文档结构?

我在构建控制器和存储库(默认 crud)后添加了 'MySubEntity'

谢谢

你不应该放 type: MySubEntity,因为我认为环回不支持这个。您在这里有 2 个解决方案:

  • 您希望 MySubEntity 只是对象中的一个字段 MyMainEntity 然后将 object 作为类型。
  • 你想要与另一个实体的关系。您可以创建一个 belongsTo 关系(参见 https://loopback.io/doc/en/lb4/BelongsTo-relation.html) 但不幸的是,据我所知,它还没有得到很好的实施。 您可以尝试在控制器中自己处理关系或 存储库代码,然后从中删除装饰器 @property 字段 subEntity.

这看起来像是 loopback-datasource-juggler 当前实现的限制 and/or LoopBack 4 将 LB4 模型定义转换为 Juggler 模型的方式。

错误由this code触发:

          // Assume the type constructor handles Constructor() call
          // If not, we should call new DataType(value).valueOf();
          this.__data[propertyName] = (value instanceof DataType) ? value : DataType(value);

Juggler 假设类型(模型)被定义为 ES5 函数,可以在有或没有 new 的情况下调用。但是,LB4 模型作为 ES6 classes 实现,必须始终使用 new 关键字构造。

我认为有两种选择,它们并不相互排斥:

无论如何,我认为这最好在 GitHub 上讨论。参见 https://github.com/strongloop/loopback-next/issues/2130