Nestjs和项目结构 - 该怎么办?
#javascript #typescript #node #nestjs

那么,您只是去巢,ey吗?您可能尚不完全理解为什么要使用NEST,或者为什么它是地球上最受欢迎的Nodejs框架之一。但是,您可以肯定地说:“如果这么多人在使用它,那一定是好的”,对吗?

好吧,这篇文章将使您对您选择巢的原因有更好的了解。

洋葱/清洁 - >巢架构

您希望您了解Onion ArchitectureClean Architecture,或者您对Separation of Concerns的全部理解有基本的了解。

,您应该拥有的其他一些知识是对Domain Driven Design的全部内容的大概。特别是“域”是什么(这与网站的名称无关)。

查看此图像。
Puh! Overwhelming, right? Borrowed from https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/puh!压倒性,对吧?从herbertograca.com借来的图像

不要在此图像中陷入困境,但是,是的,这实际上是您要确保完整的堆栈应用程序所需的一切(用任何语言,使用任何框架)。

,巢只是其中的一部分。确切的“核心”部分。

由于Nest是您系统的核心部分,因此它还涵盖了堆栈的架构的一些“层”,即:

  • 通过控制器通过控制器的REST/ RESOLERS的通信层用于GraphQL或Websockets的网关(以及Microservices的更多信息)
  • 带有ORM存储库或ODM模型或Prisma客户端的数据库抽象层
  • 带服务的业务逻辑层
  • 带警卫的访问控制层
  • 带有管道的数据转换层
  • CQRS/ BUS系统

..还有更多。

重点是,您的NEST应用程序可以做很多事情,并且想知道如何将所有这些东西放在其正确的位置,并且以某种方式模拟了该应用程序需要帮助解决的整体业务领域问题,这是一个令人生畏的任务。一开始,通常会出现问题 - 我如何构建巢应用?

这个问题通常是因为您只是在学习巢。但是,可以肯定的是,您对应用程序应该做什么有一个相当清晰的想法。

..这真的是一件好事,因为我们可以利用它来构建Nest应用程序!

但是,就目前而言,请记住,Nest将为您构建最终的“洋葱”或“干净”架构。这是Nest具有其模块系统的原因之一(以及为什么您需要将所有这些新的冗长添加到应用程序中),以及为什么Nest如此受欢迎的原因。在某种程度上,这是一种悖论。

两个域

如前所述,您有两个主要域,可以作为应用程序开发人员做事。这两个领域是

  • “开发人员域” - 有关如何使应用程序在使用框架和语言中起作用的知识”,在我们的情况下,nest and tyspript/javascript

  • “商业领域” - 有关应用程序应采取的措施解决您的业务问题的知识

当您用Nest编写代码时,您必须将这两个域融合在一起,而实际上,它们确实根本不适合。

所以,在这一点上出现问题...

我是否将代码和创建代码和框架的领域以及在内部的某个地方组织到业务逻辑?

  • 或 -

我是否尝试对我的业务领域进行建模,并弄清楚如何适应开发领域?

后者应该是您选择的一个,并且Nest的模块系统为您简化了它。

域,功能和模块

正如我们之前指出的那样,作为Nest的初学者,您可能比知道开发领域,尤其是使用Nest的开发领域要多得多知道您的业务领域。因此,从这个意义上讲,为什么不从您最了解的开始呢?

让我们使用一个新的Nest应用程序前进。

如果您还没有,install the Nest global CLI也创建了一个新项目。

New Nest app folder structure

app.controller.tsapp.service.ts只是为您提供一个运行应用程序的示例。您可以删除它们。不过要保持app.module.ts。那是您的“根”模块。

现在,让我们立即使用您的业务领域并立即使用它。假设您想构建像WordPress这样的博客应用程序,但这将是下一个最好的事情。它将比WordPress更大,更好!哈哈!我们都想要世界统治,对!

Image description
图片来源:DOOMSTEADDINER.ORG

好的。好的。也许不会。但是可以肯定的是,您确实希望解决域问题。因此,无论哪种方式,您绝对知道想要想要的。就我们的示例而言,这是一个博客应用程序。

问问自己,您可能想提供博客应用程序的总体“功能”是什么?当然,我们将开始相对简单。怎么样..

博客管理:

  • 草拟博客
  • 发布博客
  • 对博客的评论

,那用户管理呢?

用户管理:

  • 创建用户
  • 删除用户
  • 编辑用户
  • 向用户显示

最后,如何将用户带入正确的权限?

auth Management:

  • 登录用户
  • 注销用户
  • 注册用户
  • 为用户设置权限

那很简单,对吗?

创建洋葱层

现在,您可以使用Nest CLI的命令来构建您的应用。

让我们创建高级“管理”域。在您的项目文件夹中,运行以下命令:

nest generate module blog
nest generate module user
nest generate module auth

注意三件事发生了。

  • 您有具有这些域名的文件夹
  • 您有带有这些名称的模块ts文件
  • (踢脚)模块已经导入到您的app.modules.ts中。那有多酷?

Image description

Image description

现在可能是一个不错的时机,甚至在未来。您可以继续进行管理功能的模块创建过程,但是它可能过于杀伤,具体取决于必须在代码中实际做的事情才能使该功能成为现实。

您认为userauth模块将相当简单,因此您不会继续在那里添加模块。但是有了blog,嗯。...您不太确定。它可能会变得毛茸茸,更复杂,尤其是评论部分。因此,您在blog文件夹中进行。

更改为blog文件夹并运行以下命令:

nest generate module drafting
nest generate module publishing
nest generate module commenting

您最终以下图,并且再次在blog.module.ts
中自动注册模块 Image description

让我们继续转到auth模块.. ehem ...域,嗯...管理。 (请参阅此DDD的内容如何进入这里?)

好的。我们只需要三个过程。登录,注销和注册。从理论上讲,我们只看到这些是三种方法,但是这些方法可能会变得有些大。因此,我们决定为每个过程进行单数课。更改为auth目录并运行以下命令:

nest generate service login
nest generate service logout
nest generate service register

您现在有:

Image description

再次将服务自动注册到auth模块中。很好!

Image description

希望到现在为止,您正在赶上。

但是,我们需要更多的东西来使auth功能起作用。控制器如何将呼叫路由到服务?控制器应该很小,所以您知道您可以将它们全部适合一个班级。

nest generate controller auth --flat

注意--flat参数。它告诉NEST不要使用其中的控制器创建名为auth的文件夹。它将控制器文件放在当前目录中。再一次,控制器自动在auth.module.ts中注册。

好的。我们有我们的控制器,现在怎么办?

我们已经了解了guards,因此我们知道我们还需要某种守卫,以保护未来API中的某些其他道路。让我们创建它。

nest generate guard auth --flat

创建了我们的警卫。但是请注意,警卫不会自动在模块中注册。

Image description

我们可以继续使用更多的巢提供商创建,例如添加ORM文件(存储库,实体),为DTOS创建类,用于验证的管道和其他许多内容,但是您很可能会得到该类别现在的想法。

在此练习中要注意的导入零件是,我们将体系结构的所有层都放在模块中(迷你纪念)。编译时,Nest汇总了所有模块以创建完成的应用程序(大的最终踢球洋葱)。

此模块系统有一些非常好的优势:

  1. 您基本上可以采用任何模块并将其重复使用在其他地方(有一些修改)。代码重复使用!

  2. 您获得了强大的依赖注入系统。我们甚至都没有从该主题开始,但是这样的系统对于企业等级代码库非常重要,在某个时候,您的理智。

  3. 当您有一个功能问题时,您可以快速找到所需的代码。例如,假设您对博客输入的验证有问题。您转到/blog/draft文件夹,在那里您要么需要定义验证规则的DTO,要么需要进行验证的管道。全部一起。无需搜索大量文件以找到拼图的正确部分。

  4. 最后,Nest的模块化将您更多地推向了面向服务的思维方向。反过来,这将帮助您更轻松地跳到微服务。记住,我们想要世界统治!正确的?哈哈!

开玩笑。基本上,您可以说,Nest试图通过使您遵循一个模块化过程,而Nest是辅助的过程,从而试图摆脱开发。这是达到目的的一种手段,但是您的领域问题是一流的公民(或者应该是)。您手头的业务问题应决定您如何构建应用程序。 Nest只需添加整洁的工具即可实现它。

嗯....缺少东西!

您可能会说:“等一下!应用程序中不属于任何业务领域而仅属于开发人员域的应用程序呢?诸如连接到数据库或生成API之类的东西通过Swagger -或 - 配置?”

很棒的问题!

common域怎么样...嗯... ehem ...模块?

将目录更改为根并运行:

nest generate module common

我们还为上述内容创建一些服务。更改回common文件夹并运行:

nest generate module database
nest generate module swagger
nest generate module config

你去!

Image description

现在您可以从逻辑上解决问题。

结论

我希望这可以更好地了解为什么Nest的模块系统对您作为开发人员的工作如此有效。 Nest中还有许多其他功能,使他们很高兴与之合作。是的,一开始似乎是冗长的。但是,现在你知道为什么。而且,一旦您越来越多地使用NEST,您就会想知道您之前如何在没有它的情况下进行后端应用程序。

享受巢穴并玩得开心!