经过了一番长时间的网络研究后,我依然感到犹豫不决,最终还是决定使用 NestJS。为了一个要在短时间内完成的项目,我不得不放下对ExpressJS的盲目自信,选择了一个能帮我分担一些负担的工具。
该应用程序是基于微服务的,主要由客户关系管理 (CRM) 服务和库存服务组成。我的最初选择是使用 NestJS 内置的默认功能,通过 HTTP、gRPC 或 RabbitMQ 在服务之间建立通信连接。
本文将强调我遇到的一些问题,接下来,NestJS 发现系统是如何帮助解决问题的,并对一些重要概念进行解释。这可能不如预期那么全面,所以我将为有兴趣深入了解的读者们撰写几篇文章。
正如你所猜(从标题来看),典型的场景是,当比如客户更改家庭住址这样的事发生时;我们打算通知库存服务及其他对此有关注的服务。默认的 NestJS 微服务模块仅允许使用直接交换模式将消息发送到队列,但我们想让它更有趣,增加更多的服务,并允许它们监听自己感兴趣的多种事件。
我们增加了一个额外的服务,称为支付服务,它应该处理所有与支付相关的场景。该服务可能连接到一个队列,并且还关心客户的地址何时被更新。
一种流行的方法是使用 主题交换 来实现类似广播的消息路由。你可以稍微拓展一下,阅读这篇有趣的文章,文章深入解释了这些概念。
Rabbit MQ主题交换模式的示例
虽然当前的 NestJS 功能让你可以与多种消息系统进行交互,但你可能需要依赖像 nestjs-rabbitmq 这样的第三方包(由 golevelup 提供),或者自己创建一个自定义的包(我们很快就会看到如何创建)。
[@golevelup/nestjs-rabbitmq]强大的 NestJS RabbitMQ 扩展包。最新版本:5.3.0,最近更新:2 个月前。开始使用 @golevelup/nestjs-rabbitmq … www.npmjs.com自定义的 QueueModule 设置需要用到这些 npm 包,其中包括 golevelup 提供的一个发现模块。
- AMQP连接管理器
- golevelup/nestjs-discovery
- amqplib
QueueModule 是一个队列模块,它应该帮助你完成以下任务:这是一个典型的 NestJS 模块。
- 连接到消息队列(RabbitMQ)
- 扫描你项目中订阅队列事件的消费者方法
- 通过解析订阅者依赖来激活订阅方法
- 将订阅方法映射到事件
事件发射服务可以用于在应用程序的任何位置发出事件。需要注意的是,QueueModule 默认导出了该服务类,因此它随时可以使用。
控制器中调用事件和监听器仔细一看,你会发现QueueModule
试图扫描标记为带有“AMQP_SUBSCRIBER”元数据的装饰器。这个标记是每个我们感兴趣的服务方法的前缀。
用于订阅RabbitMQ事件的自定义订阅器
服务类中的事件订阅
发出自定义事件Nestjs 建议将代码或逻辑放在模块中,因此,导入 QueueModule 的模块中的服务可以使用该生产者服务。
从 QueueModule 调用生产者服务
在应用程序的任何地方触发事件
这是摘要部分
当我们使用 Nest 时,使用装饰器来创建元数据,以便后续读取和使用。这非常强大,因为框架可以检测我们应用程序的不同部分,如控制器、守卫、中间件等组件,推断它们的目的并注入必要的依赖。
尽管类型反射(反射API)虽然没有像在C#等其他语言中那样强大,我们在其他语言中拥有的类型反射,但试验性的使用装饰器和反射元数据在TypeScript生态中则是一个巨大优势,这提高了可读性,让开发人员工作更轻松。
愉快阅读🤓!