在开发后端 API 服务时,DTO 是进行参数验证生成Swagger元数据的关键节点。如果不能像推断类型一样动态推断出 DTO,那么,我们就仍然需要手工创建 DTO。随着业务的增长,复杂的表间关系会让手工补充 DTO 的工作日益繁重

而 Vona ORM 首创 DTO 动态推断与生成能力,解放我们的双手,显著提升生产力。甚至可以说,对于构建更加优雅的 Node.js 后端框架而言,能够动态推断与生成 DTO,是非常重要的里程碑

DTO清单

Vona ORM 提供了以下 DTO:

名称 说明
get 标注返回结果
query 标注Query参数
queryPage 标注带分页的Query参数
selectAndCount 标注带分页的返回结果
create 标注Create参数
update 标注Update参数
aggregate 标注聚合操作的返回结果
group 标注分组操作的返回结果

DTO使用方法

下面以 Order/Product 为例,演示如何针对主表-明细表进行查询操作

1. Model关系定义

先在 Model Order 中定义与 Model Product 的1:n关系

@Model({
entity: EntityOrder,
relations: {
products: $relation.hasMany(() => ModelProduct, 'orderId', {
columns: ['id', 'name', 'price', 'quantity', 'amount'],
}),
},
})
class ModelOrder {}
  • relations.products: 定义1:n关系

2. 创建Api端点

创建 Controller,提供 findAll 方法

class ControllerOrder {
@Web.get('findAll')
async findAll() {
return this.scope.model.order.select({
include: {
products: true,
},
});
}
}
  • model.order: 是Order的model实例
  • select:指定include.products: true,从而查询出主表-明细表数据

3. 动态推断与生成DTO

由于此 Api 返回的结果是主表-明细表结构,我们不能简单的使用EntityOrder数组来标注返回类型。而是使用 DTO 进行动态推断与生成

+ import { $Dto } from 'vona-module-a-orm';

class ControllerOrder {
@Web.get('findAll')
+ @Api.body(v.array($Dto.get(() => ModelOrder, { include: { products: true } })))
async findAll() {
return this.scope.model.order.select({
include: {
products: true,
},
});
}
}
  • @Api.body:标注返回结果
  • v.array: 标注数组
  • $Dto.get: 用于动态推断与生成 DTO

$Dto.get生成的 DTO 是主表-明细表结构,其 Swagger/Openapi 效果如下:

4. 封装DTO

我们还可以创建一个新的 DTO class,将前面的$Dto.get动态推断代码封装起来,从而用于其他地方

  1. 在 VSCode 中,可以通过右键菜单Vona Create/Dto创建 DTO 的代码骨架:
@Dto()
export class DtoOrderResult {}
  1. 使用继承机制来封装 DTO:
+ import { $Dto } from 'vona-module-a-orm';

@Dto()
export class DtoOrderResult
+ extends $Dto.get(() => ModelOrder, { include: { products: true } }) {}
  1. 现在,我们再使用DtoOrderResult重构前面的 API 代码:
class ControllerOrder {
@Web.get('findAll')
+ @Api.body(v.array(DtoOrderResult))
+ async findAll(): Promise<DtoOrderResult[]> {
return this.scope.model.order.select({
include: {
products: true,
},
});
}
}
  • 行 3: 直接使用v.array(DtoOrderResult)标注类型
  • 行 4: 方法返回类型为Promise<DtoOrderResult[]>

Vona ORM已开源:github.com/vonajs/vona

能够动态推断与生成DTO是Node生态的一个重要里程碑的更多相关文章

  1. [转]把动态页面.aspx 生成静态页面.html

    本文转自:http://blog.csdn.net/csb5201314/article/details/5391688 如果要把主页Index.aspx 生成静态页面 Index.html后输出会提 ...

  2. Java中动态代理技术生成的类与原始类的区别 (转)

    用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...

  3. Java中动态代理技术生成的类与原始类的区别

    用动态代理的时候,对它新生成的类长什么样子感到好奇.有幸通过一些资料消除了心里的疑惑. 平时工作使用的Spring框架里面有一个AOP(面向切面)的机制,只知道它是把类重新生成了一遍,在切面上加上了后 ...

  4. Flex TextInput 动态推断输入内容

    Flex TextInput 动态推断输入内容 <? xml version="1.0" encoding="utf-8"?> <s:Appl ...

  5. Angular动态表单生成(八)

    动态表单生成之拖拽生成表单(下) 我们的动态表单,最终要实现的效果与Form.io的在线生成表单的效果类似,可以参考它的demo地址:https://codepen.io/travist/full/x ...

  6. Angular动态表单生成(七)

    动态表单生成之拖拽生成表单(上) 这个功能就比较吊炸天了,之前的六篇,都是ng-dynamic-forms自带的功能,可能很多的说明官方的文档都已经写了,我只是个搬运工,而在这篇文章中,我将化身一个工 ...

  7. Angular动态表单生成(五)

    动态表单生成之布局 到上面的篇章为止,我们已经把表单比较完整的生成出来了,也实现了一些验证功能,可以说,我们截止这里,就已经可以满足我们的大部分表单生成需求了~ 但是: 目前来说,我们对于表单的布局只 ...

  8. 自动化测试尝试 动态Linq表达式生成 ftp上传

    自动化测试尝试   1. Selenium IDE Selenium IDE is a Chrome and Firefox plugin which records and plays back u ...

  9. Angular动态表单生成(一)

    好久不写博客了,手都生了,趁着最近老大让我研究动态表单生成的时机,撸一发博客~~ 开源项目比较 老大丢给我了两个比较不错的开源的动态表单生成工具,这两个项目在github上的star数量基本持平: h ...

  10. Django之动态验证码的生成

    kind.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

随机推荐

  1. HyperWorks卫星惯性释放分析(OptiStruct)

    Step01:读取模型,并设置求解器模板为 OptiStruct. (1) 读入 IGES 格式的几何模型 Exercise_9a.iges. 在绝大多数 CAE 分析中,都将从一个导入的 CAD 模 ...

  2. 十一、buildroot系统登录配置

    4.6.系统登录 4.6.1.系统登录方式配置 1.系统初始化配置选择 配置路径 : → System configuration → Init system 配置参数说明: BusyBox 简介:B ...

  3. HarmonyOS NEXT仓颉开发语言实战案例:外卖App

    各位周末好,今天为大家来仓颉语言外卖App的实战分享. 我们可以先分析一下页面的布局结构,它是由导航栏和List容器组成的.幽蓝君目前依然没有找到仓颉语言导航栏的系统组件,还是要自定义,这个导航栏有三 ...

  4. Oracle中的用户、角色和权限控制

    用户 用户分为 系统用户 和 普通用户 两类 Oracle中的用户概况 在Oracle中,视图dba_users存储了所有用户的基本信息.查看用户信息: select * from dba_users ...

  5. SpringBoot--如何给项目添加配置属性及读取属性

    SpringBoot允许使用配置文件对应用程序进行配置,支持以下不同形式的配置源: 属性文件(比如application.properties) yaml文件(后缀可以是yml或者yaml) 环境变量 ...

  6. 从零开始实现简易版Netty(三) MyNetty 高效的数据读取实现

    从零开始实现简易版Netty(三) MyNetty 高效的数据读取实现 1. MyNetty 数据读取处理优化 在上一篇博客中,lab2版本的MyNetty实现了基本的reactor模型和一个简易的p ...

  7. LINGO 解线性方程 例子

    简介 没有什么比一个例子更好讲解Lingo的了,不行那就两个... ... Question 已知某种商品6个仓库的存货量,8个客户对该商品的需求量,单位商品运价如下所示,试确定6个仓库到8个客户的商 ...

  8. 复杂文件格式如何通过ETL工具一步处理

    企业在数字化转型过程中,会面临数据孤岛及格式异构的双重挑战.传统方法处理JSON.XML.CSV等数十种混合格式时,常受限于解析效率低.转换逻辑复杂及数据质量参差等问题.而ETL工具凭借系统化数据治理 ...

  9. SciTech-EECS-一次完成“电子”和“机械”统一设计: 3D化PCB(电路板)设计 与 solidworks的3D化产品设计 完美结合

    Altium Designer做PCB设计. Altium Designer导出PCB设计为3D封装的设计文件. SolidWorks 导入Altium Designer导出的3D设计文件. Soli ...

  10. Prime Video如何将时间序列异常转化为可操作警报

    Prime Video如何将时间序列异常转化为可操作警报 Prime Video客户必须能够在所有支持该应用的设备(如手机.智能电视或游戏主机)上可靠地流式传输内容.面对海量设备类型和地区组合,Pri ...