## 介绍
当尝试学习网络时
在开发过程中,我们通常会发现前端比后端更容易访问。造成这种情况的原因有很多,尤其是更改代码中页面的某个元素并注意到应用于网站的更改所带来的即时反馈的感觉。这种反馈通常对初学者很有帮助,因为它使他们能够调整代码并从错误中学习。不幸的是,后端的情况并非如此:通常,大量的工作专门用于预先设置环境,并安装所需的依赖项,以便在终端上显示简单的“Hello World”消息。幸运的是开源社区在促进框架的开发过程方面不断取得了很多进展,NodeJs 就是一个很好的例子,该框架是一种非常强大的技术,可以让编写服务器端变得更加容易。使用 Javascript 编写代码非常方便,并提供了多种内置工具和功能,使其有别于竞争对手。在本文中,我们将通过实践方法探索 NodeJs 及其生态系统,构建一个功能齐全的项目。
我们将构建什么?
ToDo 应用程序是初学者学习前端开发的首选项目。这就是我们决定构建 Todo 列表 API 的原因。这将使我们能够将数据持久性添加到我们的界面中,并使我们能够操作这些数据(通过添加、更新、删除待办事项等……)。
最终代码可以在此处找到。
我们的工具
我们将在该项目中使用简化的技术堆栈。它可以被视为现实项目中许多工具的最小版本,原因是更高层次的想法是相同的。对于开始而言,实施细节以及特定工具的选择并不重要。
-
正如我们提到的,NodeJs 是用于构建服务器端应用程序的最流行的 Javascript 框架之一。
-
ExpressJs 是一个在 NodeJS 之上使用的最小 Javascript 框架。它通过使用许多内置功能来加快开发过程。它还被用作标准化 NodeJS 项目中的开发实践的一种方式,以方便工程师使用。
-
LowDB 是一个简单的内存数据库。它的简单性使我们能够展示如何与 NodeJs 项目中的数据库进行交互,而无需处理部署和配置等更高级的主题。
现在我们已经确定了将使用的所有工具,让我们使用键盘开始编码!
## 安装
Node 可在所有平台上使用。所有安装指南都可以在官方网站上找到。 Windows 用户应确保添加节点环境变量的路径,以便可以在命令行上使用它。
我们还需要安装 npm。 Npm 是 NodeJs 的标准包管理器。它将使我们能够管理我们的项目依赖项。安装指南可以在此处找到。
项目初始化
转到链接并克隆启动项目:
这是我们项目的一个简单的入门存储库。它包含我们将使用的所有依赖项以及项目文件结构。一旦达到,我们将解释每个元素。打开终端,导航到项目的路径并运行命令:
npm install
这将安装 package.json 文件中指定的项目的所有依赖项。 package.json 是任何 Javascript/NodeJs 项目根目录下的文件,它包含有关后者的元数据,用于管理所有项目依赖项、脚本和版本。
安装所有依赖项后,我们可以启动我们的应用程序:
npm run start
“start”是我们在包中指定的脚本。 json 文件。它指定我们应用程序的入口文件,在我们的例子中是 app.js。
现在您的终端中应显示以下消息:
这意味着我们的服务器已成功启动,并且正在侦听发送到端口 3000 的任何请求。让我们看一下 app.js 并解释一下这里发生了什么:
App.js 是我们的项目入口文件(也是目前唯一的一个)。我们实例化一个名为app的express应用程序,指定所有具有http方法“GET”和子路径“/”的请求都将由该路由处理,传入一个称为中间件的函数,该函数将请求和响应对象作为参数。这是至关重要的,因为请求包含处理它所需的所有信息(参数、请求正文、请求标头等),而响应对象是将返回给客户端的对象。我们首先发送“Hello world”消息。之后,我们让应用程序侦听对指定端口(在我们的示例中为 3000)的任何传入请求,并记录消息“侦听端口 3000”,以指示我们的应用程序已启动并正在运行并准备好接收请求。
打开终端并在链接栏中输入“localhost:3000/”,然后按 Enter 键。这是我们可以用来在本地访问我们的服务器的指定路径。您将收到以下消息:
数据库配置
Lowdb 是一个开源数据库,易于使用,无需特定设置。其背后的总体思想是将所有数据存储在本地 json 文件中。 LowDB安装完成后(我们安装所有依赖项时已经完成),我们可以在db.js中添加以下代码:
这段代码与LowDB官方文档中的代码非常相似。我们根据自己的用例对其进行了一些调整。我们逐行解释一下:
前几行用于导入必要的依赖项。 “join”是“path”模块中可用的实用函数。它是NodeJs的核心模块之一,提供了很多处理和处理路径的方法。 “Low”和“JSONFile”是LowDB 公开的两个类。第一个创建将包含我们的数据的 json 文件实例。第二个创建将对其进行操作的实际数据库实例。最后,“lodash”是最常用的 JavaScript 库之一,为常见编程任务提供各种实用函数。我们将其添加到数据库实例中,使我们能够使用其高级方法来处理我们的数据。
首先,我们指定 db.json 文件的路径。该文件将包含我们的数据,并将传递给 LowDB。如果在指定路径中找不到该文件,LowDB 将创建一个。
然后,我们将文件路径传递给 LowDB 适配器,并将其传递给新的 LowDB 数据库实例。然后可以使用“db”变量与我们的数据库进行通信。创建数据库实例后,我们使用 db.read() 从 json 文件中读取数据。这将在我们的数据库实例中设置“数据”字段,以便我们可以访问数据库内容。请注意,我们在这一行前面加上了“await”。这是为了指定该指令可能需要未知的时间来解析,并且 NodeJs 进程必须等待其执行,然后才能继续执行其余代码。我们这样做是因为读取操作需要对指定文件进行内存访问,而执行此类操作的时间取决于您的机器规格。
现在我们可以访问数据字段,我们将其设置为包含空帖子数组的对象,或者更确切地说,我们检查文件是否包含任何先前数据,如果不包含任何先前数据,则设置空数组。
最后,我们执行 db.write() 以应用我们对数据所做的修改,并导出数据库实例,以便它可以在项目中的其他文件中使用。
一般请求/响应工作流程
考虑下图:
它展示了使用 NodeJs/Express 构建的大量后端应用程序中应用的一般架构。了解处理请求背后的一般工作流程不仅可以让您构建和构建 NodeJs 应用程序,还可以让您将这些概念转移到您选择的几乎任何技术堆栈中。我们将探讨干扰此过程的不同层,并解释它们的作用:
HTTP 请求层
这是我们应用程序中的第一层,将其想象为一个网关,接收来自不同客户端的各种不同请求,然后分析每个请求并将其转发到应用程序的专用部分进行处理。
-
路由器:这里我们指的是Express路由器,但这个概念可以在许多后端框架中找到。路由器是一种将业务逻辑中的逻辑分布应用到代码中的方法,这意味着共享相似功能的每组元素都由相同的条目处理,并且可以与其余组分开。这样做的好处是使代码的每个组件彼此独立,并且更易于维护和扩展。更具体地说,作为示例,满足共享 url 路径“/posts”条件的所有请求将由同一路由器处理。根据它们的 http 方法(GET、POST 等),将使用不同的控制器。
-
控制器:控制器从路由器接收过滤后的请求,应用附加处理,并调用合适的服务方法。
业务逻辑层
该层是唯一的,具体取决于应用程序的特定用例及其背后的业务逻辑。
- 服务:服务是一组包含应用程序核心逻辑的方法。它们还通过使用 ORM/ODM
这是我们的路由器文件。我们从控制器导入express和“addPost”方法(我们很快就会实现这个),创建一个express路由器的实例,并将addPost方法绑定到我们的路由器 - 这意味着对于每个具有根路径和http的请求方法“POST”,将调用“addPost”方法来处理它。
在控制器中实现方法之前,我们在主 app.js 文件中引用新路由器,并将其路径指定为“/posts”:所有具有指定路径的路由都将转发到此路由器,因此可以处理通过不同的控制器方法:
我们导入路由器并将其命名为“posts”。 app.use(“/posts”,..) 表示所有带有子路径“/posts”的请求,无论其http方法如何,都将被路由到指定的路由器。
对 app.js 的其他更改包括导入数据库配置文件以使其执行,以及使用express.json()作为中间件以使我们能够访问请求主体对象。
现在我们的路由已经设置好了,我们可以在controller.js文件中添加“addPost”方法:
“addPost”是一个中间件函数,它将请求、响应对象和下一个函数作为参数。当调用下一个函数时,进程将移动到链中的下一个中间件,或者结束请求。在该方法的代码中,我们从请求正文中提取标题和订单,并将它们作为参数传递给服务函数“createPost”。该函数获取帖子属性,创建一个新帖子,然后返回它。创建新帖子后,我们会将其与 200 状态代码一起返回给客户端,这意味着请求已成功。您可能会注意到,我们的代码被放入 try/catch 块中,以便捕获任何意外错误,并将其传递给下一个中间件。最佳实践是在所有路由器上附加一个错误处理中间件,该中间件可提取错误并向客户端返回有意义的错误消息。
现在剩下的就是在 service.js 中实现“createPost”函数:
正如我们前面在解释架构的不同层时提到的,服务层通过使用 ORM/ODM 与数据存储解决方案进行交互。然而,在我们的示例中,我们不需要使用单独的 ORM,因为 Lowdb 内置了对 Javascript 的支持。有关其语法的所有详细信息可以在文档中找到。
“createPost”方法接收标题和顺序作为参数,并使用它们来创建帖子对象。对于唯一的 ID,我们使用一个名为“nanoid”的专用库,它会生成唯一的字符序列。我们将新帖子添加到数据库的 posts 数组中,并写入这些更改;然后该函数返回新帖子。
现在“createPost”已准备就绪,添加帖子功能现已完成并已启动并运行。我们使用 Postman(一种用于测试 API 的流行工具)对其进行测试:
我们选择“POST”作为请求的 http 方法以及指定的 url 路径“localhost:3000/posts”。我们将标题和订单以 json 格式添加到正文部分,然后发送请求。如上所示,我们收到 200 OK 状态以及新创建的帖子。
## 结论
这个项目探索了很多概念和想法:我们介绍了如何安装和设置项目环境,学习了如何配置 LowDB 以实现本地数据持久化,探索了 NodeJS/Express 后端应用程序的总体架构,并了解了如何将其应用到一个简单的例子中。最后,我们使用 Postman 测试了我们的应用程序。
这里的目的是公开构建现代后端应用程序的所有内容的简化版本。正如我们之前看到的,NodeJs 是一个强大的工具,使我们能够构建简单和复杂的 API。结合其丰富的框架生态系统(例如express)以及适用于任何用例的大量工具和库,它是现代后端开发的合法解决方案 - 我们建议学习和掌握的解决方案。