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

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

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

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

安装

到目前为止,我们还没有使用数据库来存储或操作任何数据,因此我们将建立一个数据库。 本教程将使用MySQL,如果您已经在计算机上安装MySQL,则可以继续进行下一步。

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

除了设置MySQL本身之外,我们还希望GUI软件可以查看数据库和表。 对于Mac,下载SequelPro ,对于Windows,下载SQLyog 。 下载并运行MySQL之后,可以使用SequelPro或SQLyog使用用户名root和密码root在端口3306上连接到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查询从users表中SELECT所有内容,如下所示。

SELECT * FROM users

使用pool.query()方法,这是我们新的/users获取路由的样子。

// 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 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文章中提到过,我们在URL中不使用诸如adddelete类的动词来执行操作。 为了向数据库中添加新用户,我们将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 route参数。

让我们创建一个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功能的最后一项任务是提供一个从数据库中删除用户的选项。 该请求将对WHERE使用DELETE SQL查询,并将删除route参数指定的单个用户。

// 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存储库以查看route.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表单发送请求

通常,使用HTML表单发送POST和其他更改服务器状态的HTTP方法。 在这个非常简单的示例中,我们可以在任何地方创建index.html文件,并为名称和电子邮件地址创建一个字段。 表单的操作将指向资源,在本例中为http//localhost:3002/users ,我们将方法指定为post

创建index.html并添加以下代码:

<!DOCTYPE html>
<html lang="en">

<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: 4User added with ID: 4的响应,并且您应该能够查看新的用户列表。

结论

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

至此,您应该对RESTful API的工作原理有了很好的了解,现在您可以使用Express和MySQL在Node.js中创建自己的完整API!

翻译自: https://code.tutsplus.com/tutorials/code-your-first-api-with-nodejs-and-express-connect-a-database--cms-31699

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值