独立开发者训练营(距价格上调还剩 6 天),现在报名立即启程

重构日记:应用架构选哪种?

最近重构应用,设计应用架构的时候,给新宁皓选择的是一种流式架构,感觉很好,一切都规规矩矩,整整齐齐,可扩展性也更强了。这种流式架构主要使用了 CQRS(命令与查询责任分离) 这种模式。

使用这种构架,在应用要去做一些事情,可以执行一个命令(Command),每个命令都有跟自己对应的处理器,应用里发生了什么事情,可以发布一个事件(Event), 事件都有对应的处理器。另外还有一种叫 Saga 的东西,它会监听应用里发生的所有的事情,我们可以在 Saga 里面继续处理事件,事件流是 Observable,所以可以使用 Rxjs 提供的各种操作员帮忙来处理。

比如应用要创建一个新的用户,可以触发一个创建用户命令(CreateUser),在命令对应的处理器那里可以去完成一些处理,比如把用户数据存储在数据仓库里,然后可以再发布一个用户已被创建(UserCreated)的事件,在对应的事件处理器那里可以对这个事件做出反应,比如在某个数据仓库里记录一下这个事件。另外在应用里还可以再定义一个 Saga,过滤出 UserCreated 事件,可以在这个 Saga 里继续处理这个事件,比如执行一个新的命令给用户发送一封欢迎邮件之类的。

使用这种构架的好处是,我们可以清楚的知道应用都做了些什么,在应用里都发生了什么。这种构架也非常灵活,可以轻松应对日后日益增长的业务需要,推荐大家都尝试一下,尤其是想要开发大型复杂应用的同学。这种架构会增加应用的复杂度,因为每个命令,每个事件都要单独创建各自的文件还有对应的处理器,手工创建这些文件的确很麻烦,不过我们可以借助 Angular 提供的 Schematics。

我做了一个包(ninghao-schematics),你可以在自己的 Nest.js 项目里使用它快速创建命令与事件以及对应的处理器,使用示例:

nest generate -c ninghao-schematics command create-user user/commands

上面这个命令会创建两个文件,放在 user/commands 目录的下面,一个命令的定义文件 create-user.command.ts ,另一个是命令对应的处理器 create-user.command.handler.ts,另外还会自动修改 user.module.ts,在模块文件里导入命令处理器,并且会在 providers 里面注册使用这个命令处理器。

我们可以在自己的项目里添加对应的自定义命令,这样创建命令或者事件的时候可以少输入一些东西,比如添加的命令如果是:

package.json

  "scripts": {
    ...
    "gc": "nest generate -c ninghao-schematics command"
  },

这样创建命令的时候只需要执行:

npm run gc create-user user/commands

给东西起名字被认为是软件开发领域最难的事情之一,拿到一个框架,首先我们得先了解它里面都提供什么东西,知道这些零部件的作用与制造方法,这样才能用它们设计与组装我们自己的应用。

看到陌生的名字不用太抵触,也不用被它们唬住,等熟悉了以后,你会觉得也就那么回事。我们在应用里命名一样东西,是为了让应用的结构更清晰,让各种东西都规规矩矩的。还有一个原因就是为了让大家沟通更方便,在开发者之间构建起一套交流语言。

经典的服务端应用架构:路由器(Router) → 控制器(Controller) → 服务(Service)。 应用的路由器可以决定把来自客户端的请求交给哪个控制器去处理,在控制器这里,如果有什么要做的事情可以交给某个服务方法,比如控制器可以把处理数据的活交给某个服务方法去完成,控制器最终要给客户端的请求做出响应。

假设客户端带着用户填写的用户名与密码数据请求应用的登录( /login)接口。服务端这里的路由器一看请求的地址是 /login,于是把这个请求交给可以处理用户登录的控制器方法,比如 authController.login() 。在这个控制器方法里,从请求主体里面提取出用户名与密码数据,把这些数据交给一个服务方法去验证一下,比如 authService.validateUserData,看看用户名与密码是否匹配。

服务方法把结果交给控制器,控制器可以继续处理,假设数据没问题,控制器需要给客户端响应一个签发的令牌,这个签发令牌的活也可以通过一个服务方法完成。换用流式架构以后,其实就是把经典架构里的服务(Service) 层拿掉,换成了一些命令还有事件。

宁皓网有一节课,介绍了如何在 Nest.js 应用框架里使用这种架构开发应用:https://ninghao.net/course/8047

评论

皓哥,cqrs是一个很好的应用模型,但是对于CRUD模型来说还是会有一些实践的难度,并且在nest框架文档里面也有专门介绍了CQRS,希望皓哥后续能出具相关视频详细讲讲



微信好友

用微信扫描二维码,
加我好友。



微信公众号

用微信扫描二维码,
订阅宁皓网公众号。



240746680

用 QQ 扫描二维码,
加入宁皓网 QQ 群。

统计

13356
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点