### [使用Node.js和Express编写您的第一个API:连接数据库](https://www.prosaas.cn/article/6524) **Published:** 2023-08-30T05:33:19 **Author:** 5201314 **Excerpt:** 使用 Node.js 和 Express 构建 REST API:连接数据库 在第一个教程“了解 RESTfu… ![](//zhiqipro.oss-cn-beijing.aliyuncs.com/2023/12/20231212125106165.jpg) ## 使用 Node.js 和 Express 构建 REST API:连接数据库 在第一个教程“了解 RESTful API”中,我们了解了 REST 架构是什么、HTTP 请求方法和响应是什么,以及如何了解 RESTful API 端点。在第二个教程“如何设置 Express API 服务器”中,我们学习了如何使用 Node 的内置 `http` 模块和 Express 框架构建服务器,以及如何将我们创建的应用程序路由到不同的 URL 端点。 目前,当 API 端点被 `GET` 请求命中时,我们使用静态数据以 JSON 源的形式显示用户信息。在本教程中,我们将设置一个 MySQL 数据库来存储所有数据,从 Node.js 应用程序连接到数据库,并允许 API 使用 `GET`、`POST`、`PUT`,和 `DELETE` 方法创建完整的 API。 ## 安装 到目前为止,我们还没有使用数据库来存储或操作任何数据,因此我们将设置一个。本教程将使用 MySQL,如果您的计算机上已安装 MySQL,则可以继续下一步。 如果您没有安装 MySQL,您可以下载适用于 macOS 和 Windows 的 MAMP,它提供免费的本地服务器环境和数据库。下载完成后,打开程序并单击**启动服务器**启动 MySQL。 除了设置 MySQL 本身之外,我们还需要 GUI 软件来查看数据库和表。对于 Mac,请下载 SequelPro,对于 Windows,请下载 SQLyog。下载并运行 MySQL 后,您可以使用 SequelPro 或 SQLyog 在端口 `3306` 上使用用户名 `root` 和密码 `root` 连接到 `localhost`。 在此处设置完所有内容后,我们就可以继续为 API 设置数据库。 ## 设置数据库 在数据库查看软件中,添加一个新数据库并将其命名为 `api`。确保 MySQL 正在运行,否则您将无法连接到 `localhost`。 创建 `api` 数据库后,移入该数据库并运行以下查询来创建新表。 CREATE TABLE \`users\` ( \`id\` int(11) unsigned NOT NULL AUTO\_INCREMENT, \`name\` varchar(30) DEFAULT '', \`email\` varchar(50) DEFAULT '', PRIMARY KEY (\`id\`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 此 SQL 查询将创建 `users` 表的结构。每个用户都会有一个自动递增的 ID、姓名和电子邮件地址。 我们还可以通过运行 `INSERT` 查询,使用当前通过静态 JSON 数组显示的相同数据填充数据库。 INSERT INTO users (name, email) VALUES ('Richard Hendricks', 'richard@piedpiper.com'), ('Bertram Gilfoyle', 'gilfoyle@piedpiper.com'); `id`字段不需要输入,因为它是自动递增的。此时,我们已经有了表的结构以及一些可以使用的示例数据。 ## 连接到 MySQL 回到我们的应用程序,我们必须从 Node.js 连接到 MySQL 才能开始处理数据。之前,我们安装了 `mysql` npm 模块,现在我们要使用它。 创建一个名为**data**的新目录并创建一个**config.js**文件。 我们首先需要 **data/config.js** 中的 `mysql` 模块。 const mysql = require('mysql'); 让我们创建一个 `config` 对象,其中包含主机、用户、密码和数据库。这应该引用我们制作的`api`数据库并使用默认的localhost设置。 // Set database connection credentials const config = { host: 'localhost', user: 'root', password: 'root', database: 'api', }; 为了提高效率,我们将创建一个 MySQL 池,它允许我们一次使用多个连接,而不必手动打开和关闭多个连接。 // Create a MySQL pool const pool = mysql.createPool(config); 最后,我们将导出 MySQL 池,以便应用程序可以使用它。 // Export the pool module.exports = pool; 您可以在我们的 GitHub 存储库中查看完整的数据库配置文件。 现在我们正在连接到 MySQL 并且设置已完成,我们可以继续通过 API 与数据库进行交互。 ## 从 MySQL 获取 API 数据 目前,我们的 `routes.js` 文件正在手动创建用户的 JSON 数组,如下所示。 const users = \[{ ... 由于我们不再使用静态数据,因此我们可以删除整个数组并将其替换为指向 MySQL 池的链接。 // Load the MySQL pool connection const pool = require('../data/config'); 以前,`/users` 路径的 `GET` 发送静态 `users` 数据。我们更新后的代码将改为在数据库中查询该数据。我们将使用 SQL 查询 `SELECT` 来自 `users` 表,如下所示。 SELECT \* FROM users 这是我们新的 `/users` 获取路由的样子,使用 `pool.query()` 方法。 // Display all users app.get('/users', (request, response) => { pool.query('SELECT \* FROM users', (error, result) => { if (error) throw error; response.send(result); }); }); 在这里,我们运行 `SELECT` 查询,然后通过 `/users` 端点将结果以 JSON 形式发送到客户端。如果您重新启动服务器并导航到 `/users` 页面,您将看到与以前相同的数据,但现在它是动态的。 ## 使用 URL 参数 到目前为止,我们的端点都是静态路径 - `/` root 或 `/users` - 但是当我们只想查看有关特定用户的数据时该怎么办?我们需要使用可变端点。 对于我们的用户,我们可能希望根据每个用户的唯一 ID 检索有关每个用户的信息。为此,我们将使用冒号 (`:`) 来表示它是一个路由参数。 // Display a single user by ID app.get('/users/:id', (request, response) => { ... }); }); 我们可以使用 `request.params` 属性检索此路径的参数。由于我们的名称为 `id`,因此我们将这样引用它。 const id = request.params.id; 现在,我们将在 `SELECT` 语句中添加 `WHERE` 子句,以仅获取具有指定 `id` 的结果。 我们将使用 `?` 作为占位符以避免 SQL 注入,并将 id 作为参数传递,而不是构建一个连接字符串,这会降低安全性。 pool.query('SELECT \* FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send(result); }); 我们个人用户资源的完整代码现在如下所示: // Display a single user by ID app.get('/users/:id', (request, response) => { const id = request.params.id; pool.query('SELECT \* FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send(result); }); }); 现在您可以重新启动服务器并导航到 `https://localhost/users/2` 以仅查看 Gilfoyle 的信息。如果出现 `Cannot GET /users/2` 之类的错误,则说明您需要重新启动服务器。 访问此 URL 应返回一个结果。 \[{ id: 2, name: "Bertram Gilfoyle", email: "gilfoyle@piedpiper.com" }\] 如果您看到的是这样的内容,那么恭喜您:您已成功设置动态路由参数! ## 发送 POST 请求 到目前为止,我们所做的一切都使用了 `GET` 请求。这些请求是安全的,这意味着它们不会改变服务器的状态。我们只是查看 JSON 数据。 现在我们将开始通过使用 `POST` 请求添加新数据来使 API 真正动态化。 我之前在理解 REST 文章中提到,我们不会在 URL 中使用 `add` 或 `delete` 等动词来执行操作。为了向数据库添加新用户,我们将 `POST` 到我们查看它们的同一 URL,但只需为其设置一个单独的路由。 // Add a new user app.post('/users', (request, response) => { ... }); 请注意,我们现在使用 `app.post()` 而不是 `app.get()`。 由于我们是创建而不是读取,因此我们将在此处使用 `INSERT` 查询,就像我们在数据库初始化时所做的那样。我们将整个 `request.body` 发送到 SQL 查询。 pool.query('INSERT INTO users SET ?', request.body, (error, result) => { if (error) throw error; 我们还将指定响应的状态为 `201`,它代表 `Created`。为了获取最后插入的项目的 id,我们将使用 `insertId` 属性。 response.status(201).send(\`User added with ID: ${result.insertId}\`); 我们的整个 `POST` 接收代码将如下所示。 // Add a new user app.post('/users', (request, response) => { pool.query('INSERT INTO users SET ?', request.body, (error, result) => { if (error) throw error; response.status(201).send(\`User added with ID: ${result.insertId}\`); }); }); 现在我们可以通过发送一个 `POST` 请求了。大多数情况下,当您发送 `POST` 请求时,您是通过 Web 表单执行的。我们将在本文末尾学习如何进行设置,但发送测试 `POST` 的最快、最简单的方法是使用 cURL,使用 `-d (--data)` 标志。 我们将运行 `curl -d`,后跟包含所有键/值对和请求端点的查询字符串。 curl -d "name=Dinesh Chugtai&email=dinesh@piedpiper.com" http://localhost:3002/users 发送此请求后,您应该会从服务器收到响应。 User added with ID: 3 如果您导航到 `http://localhost/users`,您将看到添加到列表中的最新条目。 ## 发送 PUT 请求 `POST` 对于添加新用户很有用,但我们希望使用 `PUT` 来修改现有用户。 `PUT` 是幂等的,这意味着您可以多次发送相同的请求,并且只会执行一个操作。这与 `POST` 不同,因为如果我们多次发送新用户请求,它会不断创建新用户。 对于我们的 API,我们将设置 `PUT` 以便能够处理编辑单个用户,因此这次我们将使用 `:id` 路由参数。 让我们创建一个 `UPDATE` 查询,并确保它仅适用于带有 `WHERE` 子句的请求 ID。我们使用两个 `?` 占位符,我们传递的值将按顺序排列。 // Update an existing user app.put('/users/:id', (request, response) => { const id = request.params.id; pool.query('UPDATE users SET ? WHERE id = ?', \[request.body, id\], (error, result) => { if (error) throw error; response.send('User updated successfully.'); }); }); 在我们的测试中,我们将编辑用户 `2` 并将电子邮件地址从 gilfoyle@piedpiper.com 更新为 bertram@piedpiper.com。我们可以再次使用 cURL,并使用 `[-X (--request)]` 标志来明确指定我们要通过其发送 PUT 请求。 curl -X PUT -d "name=Bertram Gilfoyle" -d "email=bertram@piedpiper.com" http://localhost:3002/users/2 请确保在发送请求之前重新启动服务器,否则您将收到 `Cannot PUT /users/2` 错误。 你应该看到这个: User updated successfully. 现在应该更新 ID 为 `2` 的用户数据。 ## 发送删除请求 我们完成 API 的 CRUD 功能的最后一个任务是选择从数据库中删除用户。此请求将使用 `DELETE` SQL 查询和 `WHERE`,并且它将删除由路由参数指定的单个用户。 // Delete a user app.delete('/users/:id', (request, response) => { const id = request.params.id; pool.query('DELETE FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send('User deleted.'); }); }); 我们可以再次使用 `-X` 和 cURL 来发送删除。让我们删除我们创建的最新用户。 curl -X DELETE http://localhost:3002/users/3 您将看到成功消息。 User deleted. 导航到 `http://localhost:3002`,您会看到现在只有两个用户。 恭喜!至此,API就完成了。访问 GitHub 存储库以查看 **routes.js** 的完整代码。 ## 通过`request`模块发送请求 在本文的开头,我们安装了四个依赖项,其中之一是 `request` 模块。您可以创建一个包含所有数据的新文件并将其发送,而不是使用 cURL 请求。我将创建一个名为 **post.js** 的文件,该文件将通过 `POST` 创建一个新用户。 const request = require('request'); const json = { "name": "Dinesh Chugtai", "email": "dinesh@piedpiper.com", }; request.post({ url: 'http://localhost:3002/users', body: json, json: true, }, function (error, response, body) { console.log(body); }); 我们可以在服务器运行时在新的终端窗口中使用 `node post.js` 来调用它,它与使用 cURL 具有相同的效果。如果 cURL 出现问题,`request` 模块很有用,因为我们可以查看错误、响应和正文。 ## 通过 Web 表单发送请求 通常,`POST` 和其他改变服务器状态的 HTTP 方法是使用 HTML 表单发送的。在这个非常简单的示例中,我们可以在任何地方创建一个 **index.html** 文件,并为姓名和电子邮件地址创建一个字段。表单的操作将指向资源,在本例中为 `http//localhost:3002/users`,我们将方法指定为 `post`。 创建**index.html**并向其中添加以下代码: Node.js Express REST API
在浏览器中打开此静态 HTML 文件,填写该文件,然后在服务器在终端中运行时发送它。您应该会看到 `添加了 ID 为 4` 的用户的响应,并且您应该能够查看新的用户列表。 ## 结论 在本教程中,我们学习了如何将 Express 服务器连接到 MySQL 数据库,并设置与路径和动态路由的 `GET`、`POST`、`PUT` 和 `DELETE` 方法相对应的路由参数。我们还学习了如何使用 cURL、Node.js `request` 模块和 HTML 表单向 API 服务器发送 HTTP 请求。 此时,您应该非常了解 RESTful API 的工作原理,并且您现在可以使用 Express 和 MySQL 在 Node.js 中创建自己的成熟 API! 以上就是使用Node.js和Express编写您的第一个API:连接数据库的详细内容,更多请关注知企PROSAAS其它相关文章! **Tags:** cURL, delete, express, github, html, http, https, JS, json, macos **Categories:** WordPress ---