从 NestJS 中体验装饰器的使用

1,077 阅读3分钟

在上一篇:《TypeScript 装饰器的基本语法》中,分享了如何在 TypeScript 中实现装饰器。

只不过在文章,为了说明简要的说明装饰器的实现语法,里面举的例子都没有具体的功能,只是装饰器的壳子,这样的话大家对于“我到底可以使用装饰器来做些什么”的体感不是很强烈。

所以就有了今天这篇文章,希望借助 NestJS 这一流行的服务端框架,来介绍一下各类装饰器都有哪些具体的应用场景。相当于是“抛砖引玉”,希望能给大家使用装饰器的思路带来一些启发

提示:本文主要聚焦于装饰器的应用场景和不使用情况下的对比,不会涉及它的实现原理。

为什么选择 NestJS

NestJS 是近些年流行起来的一款 Node.js服务端的框架,它认为市面上没有一款框架有效的解决了服务端JS的架构问题

However, while plenty of superb libraries, helpers, and tools exist for Node (and server-side JavaScript), none of them effectively solve the main problem of - Architecture

所以它带来了它的架构设计,希望可以帮助大家构建可测试,可扩展,松散耦合且易于维护的应用程序。

Nest provides an out-of-the-box application architecture which allows developers and teams to create highly testable, scalable, loosely coupled, and easily maintainable applications. The architecture is heavily inspired by Angular.

那它架构设计中很明显的一个风格就是大量的应用了装饰器,非常符合我们今天的主题,来探索装饰器的应用场景,体验它是否真的带来了优势

路由的映射

在绝大多数服务端应用中,当接收到来自客户端的请求时,会首先由 Router 根据请求路径判断需要讲此次的请求分发给哪个 Controller 的哪个接口来处理

之前,大多数 Node 框架实现上述的功能需要通过以下两步:

  • 定义 Controller 及其接口
  • 在 Router 中添加路由,并映射到具体的 Controller 接口

而在 NestJS 中,我们可以通过装饰器来实现这一功能:

核心就是以下两点:

  • @Controller('user') 声明了所有对 '/user/**' 的请求都被转发给 UserController 来处理;
  • @Get('list') 则进一步声明了对于 '/user/list' 的 GET 请求,需要交给 getUserList方法 来进行处理。

这样一来,我们就在实现 Controller 的同时,声明好了路由的映射关系,而且一目了然。

同时,还可以使用 @Get@Post@Put 等方法装饰器来声明对 GET、POST、PUT 等不同类型请求的处理逻辑

请求参数的处理

如果收到一个请求,我们往往需要从请求中获取参数。

当是 GET 请求时,可能是 Param 或者 Query;当时 POST 请求时,可能是 Body。

之前,大多数 Node 框架获取这个数据往往都需要我们自己来拿:

而在 NestJS 中,我们可以直接通过参数装饰器来得到目标数据:

同样的,@Param@Query@Body 这些装饰器我们获取我们所需要的目标数据

总结

这篇文章用一些极为简单的例子,看到了诸如类装饰器、方法装饰器、参数装饰器它们是如何在实际场景中使用的。

当然这些框架为我们所提供的远不止如此,装饰器的使用也有更多样化的场景值得大家去探索。

如果想更深入地了解有关于这一方面的内容,推荐大家去看 NestJS Angular 的设计和实现。

参考