如何基于动态关系进行 ORM 关联查询,并动态推断 DTO?

在上一篇文章(https://xie.infoq.cn/article/d1c1e074e9d953393e3961306)中,我们基于静态关系实现了目录树
的关联查询,并且动态推断生成了 DTO(用于 Swagger 元数据)。在这篇文章我们探讨动态关系
的用法。
什么是动态关系
那么,什么是动态关系呢?在大型业务系统中,我们会创建大量数据模型,这些数据模型之间的关联众多,我们不可能将所有关联通过静态关系
的机制事先声明出来。特别是当存在大量业务模块,这些数据模型散落在不同的业务模块中,那么通过静态关系
事先声明所有的关联关系也变得不太现实。比如,Prisma 就只支持静态关系
。如果事先没有定义静态关系
,在实际代码中,我们就需要提供一种使用动态关系
的机制,让我们的查询、类型推断、DTO 推断等能力得以正常使用。
准备数据模型
在上一篇文章中,我们已经介绍了如何创建 Entity 和 Model,这里不再赘述。而是直接把 Order 和 Customer 的 Entity 和 Model 罗列出来,然后演示动态关系
的用法
Entity
1. Order
v.openapi:声明字段的元数据,用于 Swagger
title:采用 $locale 定义,从而让 Swagger 元数据支持多语言能力
v.title:等价于 v.openapi({ title: ... })
TableIdentity:string | number
2. Customer
Model
1. Order
2. Customer
基于动态关系
的查询
现在我们查询订单列表,包含归属的顾客信息:
$relationDynamic:提供一组工具,用于定义动态关系
belongsTo:定义
多对一
的关系参数 1:Order 模型
参数 2:Customer 模型
参数 3:设置关联外键 customerId
下面我们看一下orders
的类型推断效果:


自动推断 DTO
现在我们自动推断 DTO,并且设为 API 的返回数据的类型:
行 1:动态创建
DtoOrderResult
行 17:将
DtoOrderResult
用于 Swagger/Openapi 的元数据
下面我们看一下 API 的 Swagger 效果:

封装 DTO
我们还可以创建一个新的 DTO,将前面动态创建的DtoOrderResult
封装起来,从而用于其他地方:
在 VSCode 中,可以通过右键菜单Vona Create/Dto
创建 DTO 的代码骨架:
然后我们通过继承机制来封装 DTO:
现在,我们再使用新创建的 DTO 来改造前面的 API 代码:
行 6: 直接传入
DtoOrderResult
行 7: 返回类型为
Promise<DtoOrderResult[]>
结语
Vonajs 已开源:https://github.com/vonajs/vona。
Vonajs 作者正在 B 站直播撰写技术文档,工作日每晚 8:30,欢迎围观:濮水代码直播间
评论