Nest.js + TypeORM + OpenApi 中虚拟(计算)列的最佳实践

Posted

技术标签:

【中文标题】Nest.js + TypeORM + OpenApi 中虚拟(计算)列的最佳实践【英文标题】:Best practice for virtual (computed) columns in Nest.js + TypeORM + OpenApi 【发布时间】:2021-03-07 04:04:57 【问题描述】:

我有一个实体(图像),它具有这样的计算属性(图像路径):

@Entity()
export class Image extends BaseEntity 
  @PrimaryGeneratedColumn()
  @IsInt()
  id: number

  @Column( type: 'varchar', length: 255, unique: true )
  @IsString()
  @IsNotEmpty()
  uid: string

  protected mainPath: string

  @AfterLoad()
  @AfterInsert()
  @AfterUpdate()
  generateMainPath(): void 
    this.mainPath = Math.floor(this.id / 10000) + '/' + Math.floor(this.id / 100) + '/' + this.uid
  

我使用mainPath在后端文件系统中存储图片,也将其发送到前端构建img src路径。 mainPath成功生成并发送给客户端。

问题在于前端使用 swagger (nswag openapi2tsclient) 生成的基于 openApi 模式的 typescript 文件,由 Nest.JS 生成。生成的文件中没有IImage 接口的mainPath 属性。是否可以以某种方式声明它,以便在客户端上定义它并填充来自 ajax 响应的提供值?

P.S.1。试图用@ApiProperty( type: String ) 装饰mainPath - 它没有帮助。

附注 2。尝试使用@Column( type: virtual ),但后端随后会发出警告,指出 mysql 不支持此类型。

附注 3。似乎mainPath 应该在前端声明为一些常用的非计算属性,因为它将预先填充来自后端的数据(不会在前端计算)。

附注 4。可能的方法似乎是使用裸模型作为数据库和 ExtendedImage 类,如果未提供,则在构造函数中计算 mainPath 属性。这是最佳实践吗?

【问题讨论】:

【参考方案1】:

通过使用来自class-validator 的一些装饰器,我能够得到我想要的东西。我不知道为什么会这样:

@Entity()
export class Image extends BaseEntity 
  @PrimaryGeneratedColumn()
  @IsInt()
  id: number

  @Column( type: 'varchar', length: 255, unique: true )
  @IsString()
  @IsNotEmpty()
  uid: string

  @IsString()
  @IsOptional()
  protected mainPath: string

  @AfterLoad()
  @AfterInsert()
  @AfterUpdate()
  generateMainPath(): void 
    this.mainPath = Math.floor(this.id / 10000) + '/' + Math.floor(this.id / 100) + '/' + this.uid
  

【讨论】:

谢谢你,这是完美的

以上是关于Nest.js + TypeORM + OpenApi 中虚拟(计算)列的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

如何在 typeorm 和 nest.js 中设置布尔验证

Nest.js + TypeORM + OpenApi 中虚拟(计算)列的最佳实践

Nest js 和 typeorm 自定义存储库问题

nest.js + typeORM:身份认证,事务管理

Nest.js TypeORM 连接到本地数据库(在 docker 容器上)

在 Nest JS / TypeORM 中使用具有关系的实体内部的实体并填充数据库