• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

使用Node.js和Express编写您的第一个API:连接数据库

这篇文章是名为 使用 node.js 和 Express 编写您的第一个 api的系列的一部分。 使用 Node.js 和 Express 编写您的第一个 API:设置服务器

使用 Node.js 和 Express 构建 rest API:连接数据库

在第一个教程,了解 RESTful API中,我们了解了什么是 REST 架构、什么是 HTTP 请求方法和响应,以及如何理解 RESTful API 端点。在第二个教程“如何设置 Express API 服务器”中,我们学习了如何使用Node的内置http模块和 Express框架构建服务器,以及如何将我们创建的应用程序路由到不同的 URL 端点。

GET目前,当 API 端点受到请求时,我们使用静态数据以 JSON 提要的形式显示用户信息。在本教程中,我们将设置一个 mysql 数据库来存储所有数据,从我们的 Node.js 应用程序连接到数据库,并允许 API 使用GETpostPUTDELETE方法来创建完整的 API。

安装

到目前为止,我们还没有使用数据库来存储或操作任何数据,因此我们将设置一个。本教程将使用 Mysql,如果您的计算机上已经安装了 MySQL,那么您将准备好继续下一步。

如果您没有安装 MySQL,您可以下载适用于mac OS 和 Windows 的MAMP,它提供了免费的本地服务器环境和数据库。下载完成后,打开程序并单击Start Servers以启动 MySQL。

除了设置 MySQL 本身,我们还需要 GUI 软件来查看数据库和表。对于Mac,请下载SequelPro,对于 Windows,请下载SQLyog下载并运行 MySQL 后,您可以使用 SequelPro 或 SQLyog 使用 portlocalhost上的用户名root和密码root进行连接3306

在这里设置完所有内容后,我们可以继续为我们的 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 才能开始处理数据。之前,我们安装了mysqlnpm 模块,现在我们要使用它。

创建一个名为data的新目录并创建一个config.js文件。

我们首先需要data/config.jsmysql中的模块

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');

以前,GET路径的/users是发送静态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 参数

到目前为止,我们的端点都是静态路径——要么是/根路径,要么是/users——但是当我们只想查看特定用户的数据时呢?我们需要使用可变端点。

对于我们的用户,我们可能希望根据每个用户的唯一 ID 检索有关他们的信息。为此,我们将使用冒号 ( :) 来表示它是一个路由参数。

// Display a single user by ID
app.get('/users/:id', (request, response) => {
        ...
    });
});

我们可以使用属性检索此路径的参数request.params由于我们的名字是id,这就是我们对它的称呼。

const id = request.params.id;

现在我们将WHERE在我们的语句中添加一个子句,SELECT以仅获取具有指定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 文章中提到,我们不使用类似adddelete在 URL 中的动词来执行操作。为了将新用户添加到数据库,我们将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我们可以再次使用带有[-X (--request)] 标志的 cURL 来明确指定我们正在发送 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.

2现在应该更新带有 id 的用户数据。

发送删除请求

我们完成 API 的 CRUD 功能的最后一项任务是选择从数据库中删除用户。此请求将使用带有 的DELETESQL 查询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并向其中添加以下代码:

<!DOCTYPE html> <html> <head>     <meta charset="utf-8">     
<meta name="viewport" content="width=device-width, initial-scale=1.0">     
<title>Node.js Express REST API</title> </head> <body>     
<form action="http://localhost:3002/users" method="post">         
<label for="name">Name</label>         
<input type="text" name="name">         
<label for="email">Email</label>         
<input type="email" name="email">         
<input type="submit">     
</form> 
</body> 
</html>

在浏览器中打开此静态 HTML 文件,填写并在服务器在终端中运行时发送。您应该会看到 的响应User added with ID: 4,并且您应该能够查看新的用户列表。

结论

在本教程中,我们学习了如何将 Express 服务器连接到 MySQL 数据库,并设置与路径和动态路由参数的 、 、 和 方法相对 GETPOSTPUT路由DELETE我们还学习了如何使用 cURL、Node.jsrequest模块和 HTML 表单向 API 服务器发送 HTTP 请求。



文章目录
  • 使用 Node.js 和 Express 构建 rest API:连接数据库
  • 安装
  • 设置数据库
  • 连接到 MySQL
  • 从 MySQL 获取 API 数据
  • 使用 URL 参数
  • 发送 POST 请求
  • 发送 PUT 请求
  • 发送删除请求
  • request通过模块发送请求
  • 通过 Web 表单发送请求
  • 结论