乐趣区

关于前端:Node-连载-39如何高效开发表现层-Nodejs-应用

本文是 2021 年 12 月 26 日,第三十五届 – 前端早早聊【前端搞 Node.js】专场,来自预测科技的技术总监 —— 芋头的分享。感激 AI 的倒退,借助 GPT 的能力,最近咱们终于能够十分高效地将各位讲师的精彩分享文本化后,分享给大家。(完整版含演示请看录播视频):https://www.zaozao.run/video/c35

完整版高清 PPT 请增加小助手「zzleva」获取

注释如下:

大家好,我是芋头。明天分享的主题是《如何高效开发体现层 Node.js 利用》,波及到体现层利用的开发。我明天分享的计划是针对简略场景的,旨在让前端开发人员不用把握太多对于 Node.js 的背景常识和专业知识,即便没有代码编写教训,也能实现一些简略的服务端开发工作。

有很多小公司都面临着这样的状况:大公司的开发人员更喜爱专一于业余,须要把握 ORM、服务器和运维等专业知识,但在小公司,咱们能够间接上手实现开发工作。因而,我的计划是介绍一系列工具的组合,这些工具是我在守业公司里的一些尝试,我想简略地和大家分享一下。

这里展现的就是我明天想讲的全部内容。

我的计划的底层用的是 Nest.js 开发框架,实际上,应用什么框架不是很重要,因为它只提供最根本的性能,这些性能是所有框架都具备的。Nest.js 封装了网络层和利用分层,在国外应用较多,因为它的开发方式与 Spring Boot 相似,所以对于相熟 Java 的人来说很相熟。

下层应用的是名为 Prisma 的 ORM,这是一个比拟非凡的 ORM,是一个比拟纯正的 ORM,是 Model 层的 ORM。我明天的整个计划是通过 Prisma 将所有开发流程串联起来,将多个工具连贯在一起。基本上,你只须要写很少的代码,就能够实现从底层数据层到顶层管制层再到整个 API 文档的利用开发计划。

我最近比拟关注的是这种 渐进加强 的计划,很多国外社区的计划都重视这一点。也就是说,这些计划都是可插拔的,包含我明天讲的内容,你能够抉择应用或者不应用,或者只应用其中的一部分,而不会影响其余开发工作。所以,如果你的公司还比拟小,而且想让前端负责这部分工作,你能够让他们简略地应用这些工具。然而当你的公司或者团队倒退之后,你可能须要业余的 Node.js 开发人员,他们理解 ORM、数据库、缓存等常识。这时你能够卸载下层的工具,应用 Nest.js,甚至将 Nest.js 替换成其余框架。这是一种灵便的思路,下层工具的耦合度很低,是可替换的。

这是我明天要介绍的三个外围工具,Nest.js,Prisma,GraphQL。这三者都十分重要。

Prisma

首先简略介绍一下 Prisma,Prisma 在官网上的介绍是它是「Next-generation Node.js and TypeScript ORM」,强调了它对类型的弱小反对。

对于 Prisma 的应用,实际上它是一个 ORM 工具,但它的重点并不是让你本人去定义模型、类等等,而是在进入应用时首先要定义一个形容文件。这个形容文件与相熟 GraphQL 的同学应该都晓得,GraphQL 有两种开发方式,一种是架构优先,一种是代码优先。而 Prisma 作为一个整套计划,在国外与 GraphQL 有着严密的分割,但它们之间的耦合并不是特地严格,而是比拟轻松的。

因而,在 Prisma 的开发中,首先要定义一个形容文件,其中包含

  • 定义 Model(数据模型),这是每个 ORM 都须要做的事件。
  • 定义 DataSource(数据源),这是因为在 Prisma 中,它接管了与数据库的连贯,这一层被蕴含在整个库中,所以你不须要关注如何连贯数据库,而是由 Prisma 外部进行数据库连贯的治理。
  • 定义 Generator(生成器),是 Prisma 的外围重点。它定义了数据模型和数据连贯治理形式。Generator 其实是在定义一些官网和第三方的生成工具,它能够生成强类型的 GraphQL schema 的 JS 包,生成类型的 DTO 的定义,还有 GraphQL Schema 的定义。

所以在应用 Prisma 时,你可能会发现它的用法有些奇怪。通常状况下,当你应用其余库时,你只须要间接援用 Node models 中的 ORM 的代码。然而,Prisma 中 Node models 的代码是在运行时动静生成的,它并不是在你下载下来的时候就曾经存在的。所以,在应用 Prisma 时,实际上你并没有去定义像我方才在左边代码中写的「this.prisma.tag」这样的模型,然而你却能够将它当作一个失常的对象来应用。

当然,Prisma 还有很多其余的个性,我方才只列举了一部分。

Prisma 提供了一套数据勘误的工具。实际上很多 ORM 都曾经在应用这种个性了。然而在一些小型公司或者小型产品中,应用这个工具其实十分不便。然而,在一些大型团队中,应用这种数据勘误工具可能会比拟艰难。不过,在这方面,Prisma 在这块的性能实际上做得比拟成熟。

当你须要批改一个 Model 中的任何信息时,它都会帮你生成勘误的语句,而且会进行预测,例如,如果你之前删除了一个字段,而这个字段外面有信息,并且是必填的,而你当初把它改成了非必填,那么这时候零碎会生成一条非常复杂的勘误语句,它会进行预测并让你做出抉择。

因而,在某些小型场景中,这个数据勘误工具十分不便。最初,它会生成一个勘误的记录,并能够将这个勘误记录同步到你的 Git 中。对于在生产环境中是否须要应用这套工具,这里我就不具体开展了。

Nest.js

接下来是对于 Nest.js 框架的简略介绍。这个框架实际上与许多其余框架十分相似,它实现了一些分层和全局钩子等机制,用于串联各种开发工具。我想要在 Nest.js 中尽量减少编写逻辑的数量。

因而,大家最终能够看到,在 Nest.js 端实现了一个残缺的增删改查操作,甚至包含简单的操作,基本上没有代码。因而,我只会简略地介绍一下这个框架是什么样的。

Nest.js 框架实际上有三个外围概念:Controller,Provider,Moduler。

最底层、最重要的是 Moduler,它是用来组织一个残缺业务逻辑中的所有模块的总入口。每个 Moduler 都有一个残缺的分层,入口是 Controller,所有的申请都首先进入 Controller 层。Provider 即服务层,次要提供一些相似于平时编写的 service 层逻辑的性能。

大家能够看到,这里没有明确的提到 Model 层。尽管在模型层中有一些定义,但明天咱们应用的是 Prisma,它基本上占用了 Model 层。因而,开发一个 Nest.js 的流程实际上是一个失常的开发流程,即当利用进来时,须要写 controller,service,定义 DTO 和 VO。

一旦有了 Prisma 之后,咱们能够应用 Prisma 生成一个 ORM 的库,同时它还会帮忙咱们生成一些 DTO 和 VO 的代码,所以咱们只有关注 controller 和 service。此外,Nest.js 还提供了一个用于减少、删除、批改、查问的一个脚手架。当执行了这个命令后,它会为你生成一个相似于上面这个图中的文件构造,而后你只须要填充其中的 controller 和 service 即可。

大家看似简略,只是生成了一个 Controller,而后手写了一些代码,但其实这些是十分高级的,不能帮你生成逻辑代码。所以要本人去定义参数的类型,调用 Service 层。当然,这个 Controller 层的代码还是比较简单的,不须要做太多事件,逻辑都在 Service 层。在这里须要写增删改查的逻辑,例如根本的分页和条件过滤等技术,以及联结查问等。

我不心愿前端变成一个服务端的开发者。前端写服务端的意义是什么呢?尤其对于一个小团队来说,为什么要这么做呢?其实我感觉这个框架的初衷并不是让前端变成一个服务端的开发者,而且这样做可能会受到后端开发者的质疑,我用 Spring Boot 写得很好,为什么要用 Nest.js?它有什么实质上的扭转吗?其实并没有。

所以为什么要让前端尝试去做一些服务端的开发呢?其实我初衷是为了提高效率,面对一个小的一般界面上的更改,防止前端设计师、前端开发人员和服务端开发人员都要参加能力实现此次更改,从而缩小效率损耗。我心愿前端尽量少碰服务端的代码,但同时又能灵便地调整接口,以适应前端的一直变更。所以我不心愿大家去写相似于 find、where、select、count 等这样的代码,因为对于不太熟悉这些概念的前端来说,很容易写出问题来,而且我也不心愿花太多精力去监督他们如何写这些货色。

接下来我会持续具体介绍。这里,大家能够看到 Prisma 类型是十分强的,不仅仅是模型的类型,还包含模型生成的操作类的类型,以及各种查问条件的类型,十分精密。实际上,所有应用的货色的类型都是强类型,都是依据模型定义推导进去的。因而,在它的定义中,它表明了它是一个 TypeScript 的 ORM,这是它的劣势之一。

如果你要应用 Nest.js,不论你应用什么框架,你都要做一些其余的事件,比方身份验证、异样解决、申请返回的对立封装和配置等。

网上有一些材料,但有时候形容得不是很残缺。因而,我做了一个示例,如果大家须要应用的话,能够从我的 GitHub 我的项目中 clone 进去,这样能够防止很多坑。

咱们刚刚实现了一个失常的 Nest.js 和 Prisma 的利用程序开发,实际上代码量不多,对于我这种之前做过 Node.js 服务端开发的人来说没有太大的压力。然而对于一个前端开发者来说,我向他介绍这些货色,他可能会有些难以承受,那是否能够在不编写代码的状况下实现简单的查问、插入、更新和删除逻辑,并且可能灵便调整前端界面?

GraphQL

要解决下面的问题,咱们能够引入 GraphQL,这实际上是一种面向前端的接口凋谢形式。GraphQL 并不是一个万能药,不是说通过 GraphQL 提供的接口就变得高级了,或者解决了很多问题。实际上,它只实用于某些场景,特地是它最后设计的树状数据结构,而不是图状数据结构,可能在树状数据结构的场景下更加适宜。

然而明天我的话题外围实际上是 Prisma 和 GraphQL 的配合。尽管 Prisma 的官网定义中没有提到这一点,然而如果你查看官网文档,它有一个对于 Prisma 和 GraphQL 如何一起应用的话题。

在这里我应用了两个工具。

prisma-nestjs-graphql

第一个工具是我要用 Prisma 的 Schema 生成 GraphQL 的 Schema,这个工具切实一直演进。我应用的是它之前的一个版本,prisma-nestjs-graphql,这个库的名字十分直白,就是将这三者连接起来,通过执行 Prisma 的 generate 命令,能够在我的项目中生成内容。生成的内容不仅包含 Model 的定义(例如 tags),还会生成一些定义这些操作的参数。

我的查问操作非常灵活,包含了 where 条件、in、order by、group by、count、分页 等操作,而这个工具能够生成这些操作所需的文件。当我生成了这些文件并引入了这个插件后,我的代码就产生了变动。

这里 Resolver 实际上是用于 GraphQL 开发的,相似于 Controller 的一个分层,实际上 Resolver 内的逻辑没有产生太大的变动。尽管它与 Controller 的定义有些相似,然而到了 Service 层,你会发现一个神奇的事件,它外部没有代码。在失常的开发中,Service 层通常须要编写调用 ORM 的代码,但在这里,基本上是透传的,你能够间接透传 update、delete、count 等操作。当然,在这里你也能够编写失常的查问操作,但在一般状况下,你只须要透传这些操作 Resolver,Resolver 会间接透传给前端。

swagger-to-graphql

在理论开发过程中,前端代码还须要拜访服务端之前开发的接口。为了使这些接口与前端代码的数据拜访更好地联合,须要应用 swagger-to-graphql 工具,它能够将 Swagger 的格局(即 Open API 的规范格局)转换为 Graphql 数据模型,使得前端代码能够间接拜访服务端的接口。这个库的应用非常简单,只需传入一个 Swagger 文档,定义一个 Provider,把 Swagger 的数据传进来,就会主动生成一个透传的 GraphQL 接口供应用。能够在 GraphQL 的视图中看到服务端定义的接口以及所有可用的查问参数。

最初

以上就是我的全副分享,我介绍了最根本的三个货色,即 Nest.js、Prisma 和 GraphQL,以及我用到的一些工具。

我没有深刻解说 Prisma 框架外部如何实现之前在 Service 外面一行代码都不写的状态,这是因为 Prisma 自身能够自适应到 GraphQL 的 Resolver 下面去,这是一般的 ORM 库难以实现的。另外,明天我将的内容都能够在我的 GitHub 仓库中找到。如果你对这个话题感兴趣,能够去找找我的仓库,外面包含了一些鉴权、错误处理和返回后果的封装,还有对于 Nest.js 的一些货色,十分不便用于小型利用的开发。


退出移动版