回到最初的ValidationPipe,它是一个强大的校验工具,我们看到前面的controller代码中插入操作中有一个CreateCatDto,dto是一种数据传输对象,一个dto可以这样定义:
export class CreateCatDto { @IsString() readonly name: string; @IsInt() readonly age: number; @IsString() readonly breed: string; }然后ValidationPipe会检查body是否符合这个dto,如果不符合就会就会执行你在pipe中设置的处理方案。具体是如何实现的可以再写一篇文章了,所以我推荐你看nest中文指南(顺便感谢翻译的同学们)
示例的完整代码可以看01-cats-app
也就是说业务团队中的熟练工或者架构师可以开发大量的模块,中间件,异常过滤器,管道,看守器,拦截器等等,而不太熟练的开发者只需要完成controller的开发,在controller上像搭积木般使用这些设施,即完成了对业务的完整搭建。
Nesk-一个落地方案的尝试虽然我个人很喜欢Nest,但是我们公司已经有一套基于koa2的成熟框架Aconite,而Nest是基于express的,查看了下Nest的源码,对express有一定的依赖,但是koa2和express在都支持async语法后,差异属于可控范围下。另外nest接受一个express的实例,在nesk中我们只需要调整为koa实例,那么也可以是继承于koa的任何项目实例,我们的框架在2.0版本也是一个在koa上继承下来的node框架,基于此,我们只需要一个简单的adapter层就可以无缝接入Aconite到nesk中,这样减少了nesk和内部服务的捆绑,而将所有的公共内部服务整合保留在Aconite中。Nest对于我们来说只是一个更完美的开发范式,不承接任何公共模块。
所以我们需要的工作可以简单总结为:
支持Koa
适配Aconite
支持Koa我们在Nest的基础上做了一些小改动完成了Nesk来兼容Koa体系。我们只需要完成Nesk和Aconite中间的Adapter层,就可以完成Nesk的落地,最后启动处的代码变成:
import { NeskFactory } from '@neskjs/core'; import { NeskAconite } from '@hujiang/nesk-aconite'; import { ApplicationModule } from './app.module'; import { config } from './common/config'; import { middwares } from './common/middlware'; async function bootstrap() { const server = new NeskAconite({ projectRoot: __dirname, middlewares, config }); const app = await NeskFactory.create(ApplicationModule, server); await app.listen(config.port); }最后Nest有很多@nest scope下的包,方便一些工具接入nest,如果他们与express没有关系,我们其实是可以直接使用的。但是包内部往往依赖@nest/common或者@nesk/core,这里可以使用module-alias,进行一个重指向(你可以尝试下graphql的例子):
"_moduleAliases": { "@nestjs/common": "node_modules/@neskjs/common", "@nestjs/core": "node_modules/@neskjs/core" }Nesk的地址Nesk,我们对Nesk做了基本流程测试目前覆盖了common和core,其它的在等待改进,欢迎一切愿意一起改动的开发者。
不足与期待其实从一个更好的方面来说,我们应当允许nest接受不同的底层框架,即既可以使用express,也可以使用koa,通过一个adapter层抹平差异。不过这一块的改造成本会大一些。
另一方面nest有一些本身的不足,在依赖注入上,还是选择了ReflectiveInjector,而Angular已经开始使用了StaticInjector,理论上StaticInjector减少了对Map层级的查找,有更好的性能,这也是我们决定分叉出一个nesk的原因,可以做一些更大胆的内部代码修改。另外angular的依赖注入更强大,有例如useFactory和deps等方便测试替换的功能,是需要nest补充的.
最后所有的基于Koa的框架都会问到一个问题,能不能兼容eggjs(:)),其实无论是Nest还是Nesk都是一个强制开发规范的框架,只要eggjs还建立在koa的基础上,就可以完成集成,只是eggjs在启动层面的改动较大,而且开发范式和nest差异比较多,两者的融合并没有显著的优势。
总之Node作为一个比较灵活的后端开发方式,每个人心中都有自己觉得合适的开发范式,如果你喜欢这种方式,不妨尝试下Nest或者Nesk。