NestJS + Typeorm + Graphql:嵌套关系中 DTO 的正确设计模式

Posted

技术标签:

【中文标题】NestJS + Typeorm + Graphql:嵌套关系中 DTO 的正确设计模式【英文标题】:NestJS + Typeorm + Graphql: correct design pattern for DTO in nested relations 【发布时间】:2019-10-22 13:17:04 【问题描述】:

假设我有一个这样的 Typeorm 实体定义:

@Entity()
export class MyEntity 
  @PrimaryGeneratedColumn()
  id: number;

  @Column('varchar',  length: 500 )
  name: string;

  ...

  @OneToOne(type => DocumentEntity)
  @JoinColumn()
  myDoc: DocumentEntity;

  @OneToMany(type => DocumentEntity, document => document.myEntity)
  @JoinColumn()
  otherDocs: DocumentEntity[];

  ...

所以它有几个实体关系,OneToMany/OneToOne

在制作我的 DTO 时如何处理这个问题?

这里我有一个 DTO 示例:

export class CreateMyEntityInputDto 

  @IsString()
  name: string;

  ...

  @IsOptional()
  myDoc: DocumentEntity;

  @IsOptional()
  otherDocs: DocumentEntity[];

  ....

我不清楚通过 Graphql 的最佳方法

当前的graphql界面:

####################
# @input
####################
input CreateDealInput 
  name: String
  ...
  myDoc: DocumentInput
  otherDocs: [DocumentInput]
 

如果我正在设计“传统”RESTful 服务,我将通过单独的端点在数据库中创建我的文档,等待返回 documentID(s):int 的成功

然后在 myEntity.myDoc / myEntity.otherDocs 中将这些 id 指定为纯整数 创建新的myEntity(在单独的端点)时的字段。

我在这里采取同样的方法吗? ie我是否在 graphql 的单独查询中创建文档实体,从成功响应中解析出创建的 id,然后在 DTO 定义中指定这些 int 值? p>

类似:

@IsOptional()
myDoc: int;

然后,在创建 myEntity 时,通过 id:int 加载那些(现有)文档实体,然后最终通过 Typeorm 保存?

或者我是否将所有文档字段作为嵌套实体传递到一个大型嵌套 POST graphql 查询中并使用级联来创建它们?

【问题讨论】:

【参考方案1】:

我自己也遇到了同样的问题。我的解决方案是通过 id 引用嵌套实体。在您的示例中,这将类似于:

export class CreateMyEntityInputDto 

  @IsString()
  name: string;

  ...

  @IsOptional()
  myDocId: string;

  @IsOptional()
  otherDocIds: string[];

  ....

此解决方案不是在一个突变中创建嵌套实体,而是需要多个。

【讨论】:

以上是关于NestJS + Typeorm + Graphql:嵌套关系中 DTO 的正确设计模式的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:存储库方法不是函数(NestJS / TypeORM)

过滤从查询参数传递的数组。 NestJS,TypeORM

NestJS + TypeORM 中的 JoinTable 问题

NestJS + TypeORM:使用两个或更多数据库?

播种时NestJS中的TypeOrm:RepositoryNotFoundError

在 Nestjs 中注入 Tree Typeorm 存储库