VonaJS 5.0 隆重推出自动推断生成 DTO 的功能
在Nodejs生态中,Prisma是一个非常流行的ORM库,支持Typescript,提供了非常友好的类型推断能力。但是,Prisma却不能优雅的支持DTO。在与其他后端框架整合时,DTO是进行参数验证、生成Swagger元数据的关键节点。如果不能像推断类型一样自动推断出DTO,那么,我们就仍然需要手工创建DTO。随着业务的增长,复杂的表间关系会让手工补充DTO的工作日益繁重。
而VonaJS 5.0就提供了非常便利的工具,使我们可以非常直观的动态推断出DTO,就像推断类型一样,从而解放我们的双手,显著提升生产力。甚至可以说,能够自动推断DTO,为Nodejs后端框架打开了一扇窗。
限于篇幅,这里不展开讲解Vona ORM所有的知识点,而是以目录树
为例,演示如何查询一棵目录树,以及如何动态生成DTO,并最终生成Swagger元数据。
1. 创建Entity
在VSCode中,可以通过右键菜单Vona Create/Entity
创建Entity的代码骨架:
@Entity('demoStudentCategory') export class EntityCategory extends EntityBase { @Api.field() name: string; @Api.field(v.optional()) categoryIdParent?: TableIdentity; }
- 行2: 继承自EntityBase,就会自动提供5个基础字段:id、createdAt、updatedAt、deleted、iid
- iid:是实例Id,通过多实例的机制支持多租户系统的开发
- 行4、7: 定义两个业务字段:name、categoryIdParent
- @Api.field:通过此装饰器定义的信息,可同时应用于参数验证和Swagger元数据
- v.optional:声明为可选字段
2. 创建Model
在VSCode中,可以通过右键菜单Vona Create/Model
创建Model的代码骨架:
import { EntityCategory } from '../entity/category.ts'; @Model({ entity: EntityCategory }) export class ModelCategory extends BeanModelBase {}
- 行3: entity:指定Model所对应的Entity
- 行4: 继承自BeanModelBase,从而拥有大量操作数据库的方法,如:CRUD、聚合、分组,等等
3. 创建树形结构
如果要创建一棵目录树,本质就是建立Model引用自身的递归结构。Vona ORM同样支持4种关系:1对1
、1对多
、多对1
,多对多
。那么,在这里,我们就需要采用1对多
来创建目录的自身引用关系。
import { EntityCategory } from '../entity/category.ts'; @Model({ entity: EntityCategory, + relations: { + children: $relation.hasMany(() => ModelCategory, 'categoryIdParent', { + autoload: true, + columns: ['id', 'name'], + }), + }, }) export class ModelCategory extends BeanModelBase {}
- 行5: relations:可以定义多个关系
- 行6: children:定义一个1对多的关系
- $relation.hasMany:
- 参数1: 引用自身ModelCategory
- 参数2: 设置关联外键categoryIdParent
- 参数3: 关联选项
- autoload:是否自动加载关联数据
- columns:控制关联数据的字段列表
4. 创建Controller
在VSCode中,可以通过右键菜单Vona Create/Controller
创建Controller的代码骨架:
@Controller() export class ControllerCategory extends BeanBase {}
接下来我们创建一个Api,用于获取目录树:
export class ControllerCategory extends BeanBase { @Web.get('getCategoryTree') async getCategoryTree() { } }
- 行2: 通过@Web.get定义一个api,path为getCategoryTree
5. 查询目录树
一般而言,我们还需要创建一个Service,从而实现以下调用链:Controller->Service->Model->操作数据库。为了简化起见,在这里,我们直接在Controller中调用Model方法:
export class ControllerCategory extends BeanBase { @Web.get('getCategoryTree') async getCategoryTree() { const tree = await this.scope.model.category.select({ columns: ['id', 'name'], }); return tree; } }
- 行4: 通过
this.scope
取得Category Model,然后调用select方法- columns:指定要查询的字段列表
由于前面我们设置children关系为autoload: true
,因此,查询结果tree
就是一棵完整的目录树。下面我们看一下tree
的类型推断效果:
6. 自动推断DTO
现在我们自动推断DTO,并且设为API的返回数据的类型:
export class ControllerCategory extends BeanBase { @Web.get('getCategoryTree') + @Api.body(v.array(v.object($Dto.get(() => ModelCategory, { columns: ['id', 'name'] })))) async getCategoryTree() { const tree = await this.scope.model.category.select({ columns: ['id', 'name'], }); return tree; } }
- 行3: 通过@Api.body定义API返回数据的类型:
- v.array:定义数组类型
- v.object:定义对象类型
- $Dto.get:动态推断DTO
- 参数1:指定目标Model
- 参数2:指定选项
- columns:指定要提取的字段列表
同样,由于前面我们设置children关系为autoload: true
,因此,$Dto.get
生成的DTO就是一棵完整的目录树。下面我们看一下API的Swagger效果:
从示意图中,我们可以清晰的看到,这棵树引用的children类型是名称为demo-student.entity.category_2c7d642ee581efa300341e343180fbb0ecdc785d
的动态Entity的数组,从而形成一种递归的引用关系。
7. 封装DTO
虽然我们已经实现了预期的目标,但是Vona ORM提供的能力还没有结束。我们可以创建一个新的DTO,将前面的代码$Dto.get(() => ModelCategory, { columns: ['id', 'name'] })
封装起来,从而用于其他地方:
在VSCode中,可以通过右键菜单Vona Create/Dto
创建DTO的代码骨架:
@Dto() export class DtoCategoryTree {}
然后我们通过继承机制来封装DTO:
@Dto() export class DtoCategoryTree + extends $Dto.get(() => ModelCategory, { columns: ['id', 'name'] }) {}
现在,我们再使用新创建的DTO来改造前面的API代码:
export class ControllerCategory extends BeanBase { @Web.get('getCategoryTree') + @Api.body(v.array(v.object(DtoCategoryTree))) + async getCategoryTree(): Promise<DtoCategoryTree[]> { const tree = await this.scope.model.category.select({ columns: ['id', 'name'], }); return tree; } }
- 行3: 直接传入
DtoCategoryTree
- 行4: 返回类型为
Promise<DtoCategoryTree[]>

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
源雀 SCRM 开源版升级:企业公告功能上线,高效触达更灵活!
一:核心功能更新:企业公告开源 本次开源版重磅推出「企业公告」模块,支持通过企业微信应用向指定员工发送多样化通知: 开源功能: ✅ 文本通知:快速传达政策变更、任务安排等关键信息。 ✅ 图片/图文消息:支持上传产品手册、流程图示,信息呈现更直观。 ✅ 精准定向:按部门、角色或员工名单灵活选择接收对象,避免信息过载。 ✅ 历史消息:发送记录自动存档,便于审计与复盘,保障沟通透明度 商业版在开源基础上新增: 👏 视频文件推送:适用于培训教学、产品演示等需动态展示的场景。 👊 定时通知:预设发送时间,确保重要公告在最佳时机触达(如节假日提醒、活动预热)。 👍 通知撤回: 误发内容一键撤回,降低沟通事故风险。 二、典型应用场景 行政办公:HR通过图文公告一键下发考勤制度,员工企微实时查收。 销售协同:区域经理定向推送产品报价图,一线团队快速响应客户需求。 培训管理(商业版专属):上传教学视频,新人可反复观看学习业务流程。
- 下一篇
openKylin 2.0 SP2 揭秘 - 磐石架构究竟有多 “能打”?
前文中,我们探讨了磐石架构的起源,并了解了OpenAtom openKylin(简称“openKylin”)磐石架构的组成框架,主要包括不可变系统、KARE兼容环境、开明包格式三大核心技术。今天,我们将深入剖析 openKylin 磐石架构相较于其他现有架构的关键优势所在。 不可变系统—核心系统固化 传统 Linux 桌面系统的核心痛点之一是配置碎片化与误操作风险。例如,用户手动修改系统文件可能导致依赖冲突,而恶意软件通过篡改关键组件可轻易入侵系统。磐石架构通过不可变系统设计重构这一模式: 1. 坚如磐石的稳定性 ● 核心只读固化:将操作系统核心组件(内核、基础库)封装为不可修改的镜像,用户操作与应用运行均在独立的可写层完成,从根本上杜绝误删文件、依赖冲突等问题。 ● 容器化隔离:应用程序与核心系统隔离,单应用故障不影响系统整体运行。 2. 本质级安全防护 ● 防御系统篡改:系统状态不可改变,攻击者无法修改系统。 ● 阻断污染传播:应用无法修改系统核心文件,破坏性操作无法扩散至核心系统层。 3. 零风险运维革命 ●问题好重现:操作系统在启动时内容一致不变,更容易测试、审核和验证系统,以...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,CentOS7官方镜像安装Oracle11G
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS8安装Docker,最新的服务器搭配容器使用
- Hadoop3单机部署,实现最简伪集群
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS关闭SELinux安全模块