🛠背景
由于个人偶尔需要做前后端开发,所以想参考ruoyi的思路想搭建一个快速开发工具,在摸索了一段时间后,理想架构如下:
- 前端:Vue3 + TS,通过脚本自动解析Swagger生成接口类型,或直接使用Alova
- 后端:NestJS(学习一下热门框架)
- ORM:Prisma,喜欢它的轻量手感、统一Schema管理和内置的一些脚本,以及官方描述的迁移成本低(考虑到根据不同项目可能用不同的数据库)
graph TD
A[后端] -->|NestJS+Prisma| 接口 --> 开发
A[后端] -->|swagger| 文档 --> B[前端Vue3+TS] -->|脚本| 自动API和类型生成 --> 开发
🔥 踩坑
想法很美好,做一步走一步。其中Nestjs + Prisma结合,导致的类型打架是我感受到最大的痛点
Prisma生成的是纯类型接口(Interface),而NestJS生态重度依赖类(Class),如一些传参校验Dto,就无法和prisma进行结合
// Prisma生成的泛型类型(接口)
type User = {
id: number
name: string
posts: Post[]
}
// NestJS需要的DTO类
export class CreateUserDto {
@ApiProperty() // Swagger装饰器
@IsString() // 校验装饰器
name: string
}
虽然分别维护可以处理,官方文档也提了有能够支持转成dto的插件,但是不太好用。
个人也写了一个魔改的版本,Prisma在执行npx prisma generate
命令生成的时候,输出一个基于prisma.schema
生成的Dto,但也用不太上,目前来看比较好的就是分别维护Dto和Prisma类型
因为我需要根据Swagger文档生成相应的接口类型和接口方法,需要去维护,麻烦就来了
在Nestjs中Swagger文档类型需要接受一个类(Class)
传入,而不是一个类型,如果传入类型,Swagger不会识别
// 有效声明(类+装饰器)
@Post()
createUser(@Body() params: CreateUserDto) {}
// 无效声明(接口类型)
@Post()
createUser(@Body() params: Prisma.UserCreateInput) {} // Swagger无法识别
其次,如果有关联的表,在Service层操作时,关联表的类型也无法传入自己写的Dto,Prisma的api会警告参数需要使用Prisma自己的类型,而他自己的类型又是一个泛型!
当然可以不传入Dto,结果也是能走通,但是对于需要维护Swagger文档的项目来说,直接使用Prisma类型会导致文档缺失
我也找了看有没有解决这个痛点的文章,但好像都没有说,所以我个人的结论是,Nestjs官网应该表明**不建议搭配Prisma使用!**最后我还是打算换回Nestjs官网首推的Typeorm
🥹总结
总结是,不要硬磕,NestJS+Prisma组合可能更适合有独特的开发思路的高超技术人员
我认为Prisma可能比较适合类似nuxt、next之类的框架去使用,体感会好很多,而在nestjs这种重度依赖类的框架强制使用prisma,有点背道而驰
转 Typeorm 后,看着我终于正确的 swagger 文档和前端接口类型,那个困了我一辈子的心结,终于解开了