Node Web后端框架 Express 的学习 --- 终

目录

引言

在前面的学习中,我们成功搭建了Express框架,并领略了其轻量级和易于上手的特点,这为我们的Web应用开发奠定了坚实的基础。然而,Express框架的精髓远不止于此。其真正强大的地方在于它拥有一个丰富且成熟的生态系统,这个生态系统中最引人注目的便是中间件(Middleware)机制。

中间件作为Express框架的灵魂,不仅扩展了框架的功能,还提高了应用的灵活性和可维护性。通过中间件,我们可以轻松地对请求和响应进行预处理和后处理,实现诸如日志记录、身份验证、错误处理等功能。更重要的是,Express的中间件机制允许我们编写可复用的代码片段,这些代码片段可以在多个应用中共享,大大提高了开发效率。

在本文中,我们将使用Express的中间件,了解如何使用它们来构建更加健壮和高效的Web应用。希望通过本文的学习,读者能够深刻体会到Express框架中间件的强大之处,并在自己的项目中灵活运用它们。

一、开发环境必备:数据库

1.1 本地环境创建数据库

本篇使用的是MySQL,而其他数据库,基本大差不差。

-- 创建数据库
CREATE DATABASE IF NOT EXISTS db_min

-- 创建用户表
CREATE TABLE IF NOT EXISTS user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(50) NOT NULL
)

-- 插入六条数据
INSERT INTO user (username, password) VALUES
('张三', '123456'),
('李四', '123456'),
('王五', '123456'),
('赵六', '123456'),
('老王', '123456'),
('小三', '123456')

1.2 连接数据库

在Node.js的Express框架中,连接MySQL数据库可以通过两种主要方式实现:

  1. 使用mysql2原生客户端mysql2是MySQL的官方Node.js客户端,它允许你直接与MySQL数据库进行交互。这种方式比较直接和底层,你可以精确控制数据库操作,执行SQL查询,获取结果。但这也意味着你需要自己处理所有的SQL语句,并且要特别注意防止SQL注入等安全问题。
  2. 使用mysql2 + knex组合knex是一个SQL查询构建器,它提供了一个更高级的抽象层,让你可以用JavaScript代码来构建SQL查询,而不是直接编写SQL语句。knexmysql2结合使用,可以让你以一种更简洁、更安全的方式操作数据库。knex支持多种数据库,包括MySQL,并且提供了诸如事务管理、迁移、连接池等高级功能。

简单来说,如果你喜欢直接控制数据库操作,不介意手动编写SQL语句,可以选择使用mysql2。如果你希望以一种更现代、更安全的方式来管理数据库操作,并且想要利用一些高级功能,那么mysql2结合knex可能是更好的选择。

1.2.1 使用mysql2原生客户端

安装 mysql2
npm install mysql2
② 编写数据库配置文件
//src/common/config/index.js
module.exports = {
    MySQLConfig: {
        host: "localhost",
        user: "root",
        password: "123456",
        database: "db_min",
        // 是否等待所有连接都被处理。如果设置为true,则当连接池达到其最大容量时,新请求将被阻塞,直到有可用连接
        waitForConnections: true, 
        connectionLimit: 10, // 允许的最大连接数。如果超过这个数量,新的连接将被拒绝
        // 队列限制。如果设置为0,则没有限制,更多的请求将被添加到队列中,直到达到最大连接数
        queueLimit: 0, 
    },
};
③ 连接数据库
//src/common/utils/db.js
const mysql = require("mysql2");
const { MySQLConfig } = require("../config");

// 创建连接池
const pool = mysql.createPool(MySQLConfig);

module.exports = pool.promise();
④ 使用数据库
// UserDao.js
const db = require("../common/utils/db");
class UserDao {
    async getUserList() {
        let sql = "select * from user";
        const data = await db.execute(sql);
        // 使用 data[0] 的原因,请查阅 mysql2 文档。本文重点在快速实践,深入理论需自行学习。
        // 如果你深入理论学会后,还望慷慨分享,让我们共同成长和学习。
        return data[0];
    }
}
module.exports = new UserDao();

1.2.2 使用mysql2 + knex组合

安装 mysql2knex
npm install knex mysql2
初始化 knex
//src/common/config/index.js 
module.exports = {
    MySQLConfig: {
        client: "mysql2",
        connection: {
            host: "localhost",
            user: "root",
            password: "123456",
            database: "db_min",
        },
        pool: {
            // 连接池配置
            min: 0,
            max: 10,
        },
    },
};
创建和使用 knex 实例
//src/common/utils/db.js
const { MySQLConfig } = require("../config");
const knex = require("knex")(MySQLConfig);
// 监听 'query' 事件
knex.on("query", (query) => {
    console.log("SQL Statement:", query.sql);
});

// 监听 'query-response' 事件,获取查询结果
knex.on("query-response", (response, query) => {
    console.log("SQL Query Result Count:", response.length);
});

module.exports = knex;
//UserDao.js
const db = require("../common/utils/db");
class UserDao {
    async getUserList() {
        return await db.select('*').from('user');
    }
}
module.exports = new UserDao();

1.2.3 校验接口

image.png

1.2.4 总结

两种方式都允许你将Express.js应用连接到MySQL数据库,但使用knex提供了一个更高级的抽象,使得查询构建、事务处理和数据库迁移等操作更为简单和安全。而直接使用mysql2则提供了更直接的控制,可能更适合那些需要精细调整数据库操作的场景。

萝卜青菜各有所爱,具体还是看业务需求。笔者个人更倾向于mysql2knex的组合使用,既享受了knex带来的便利,又不失对数据库操作的精细控制。

二、接收POST请求

因为Express开发初期,目的在于轻量级,从而舍弃了部分功能,而解析POST请求便被舍弃了,故而在4.x以前,一般使用body-parser来解析。

但在 Express 4.x 以后的版本,body-parser已经内置于 Express 框架中。

所以,笔者在这里还是将两种方法都写一遍,以免读者使用了 4.x 以前的版本却又不会解析POST请求

2.1 方式一:内置版

//src/index.js
const express = require("express");
const app = express();

// 使用 express.json() 中间件来解析 JSON 格式的请求体
// 使用 express.urlencoded() 中间件来解析 URL 编码的请求体  
app.use(express.json(), express.urlencoded({ extended: true }));

app.use(require("./common/utils/morgan")); // 日志

app.use("/", require("./controller")); // 路由分离
module.exports = app;

2.2 方式二:body-parser

//src/index.js
const express = require("express");
const bodyParser = require("body-parser");
const app = express();

// 解析POST
app.use(bodyParser.json(), bodyParser.urlencoded({ extended: true }));

app.use(require("./common/utils/morgan")); // 日志

app.use("/", require("./controller")); // 路由分离
module.exports = app;

2.3 编写接口

// UserControler.js
UserControler.post("/", async (req, res) => {
    res.send(Result.success(await req.body));
});

2.4 校验接口

image.png

三、日志中间件

当我们的应用程序连接到数据库并提供了一系列接口后,有时我们可能不太清楚这些接口的具体行为,或者当遇到大量请求时,我们无法确定是哪些IP地址在频繁访问我们的系统。这时,引入日志中间件,如Morgan,就显得尤为重要。

日志中间件可以帮助我们记录每个请求的详细信息,包括请求的IP地址、请求方法、路径、状态码以及响应时间等。这样,我们不仅能够监控接口的使用情况,还能够在出现问题时快速定位和诊断问题。

通过使用Morgan,我们可以轻松地为Express.js应用程序添加日志记录功能,从而提高系统的可维护性和安全性。

安装 Morgan

npm i morgan

使用

//src/common/utils/morgan.js
const morgan = require("morgan");

// 请求IP 方法 状态 路径 响应时间
module.exports = morgan(
    ":remote-addr :method :status :url :response-time ms"
);

这里需要注意,日志中间件的导入需要在路由前,Express的设计是一层层的,往下走,而中间件的使用顺序就在此尤为重要了

//src/index.js
const app = require("express")();

app.use(require("./common/utils/morgan")); // 日志

app.use("/", require("./controller")); // 路由分离
module.exports = app;

结语

至此,我们成功构建了一个集成了MySQLKnexMorgan的后端简易开发系统。该系统不仅体现了Express框架的轻量级和灵活性,还借助强大的中间件生态实现了更多高级功能。受限于篇幅和笔者的技术水平,我们无法对所有的中间件和框架原理进行详尽的解析,但本文旨在为所有对Express框架感兴趣的读者提供一个清晰、简洁的入门指南。

对于希望快速构建项目原型的读者,本文提供了实用的指导;我相信,通过本文的学习,你将能够初步掌握Express框架的使用方法,并在实践中不断提升自己的技能。

为了让你更深入地了解本项目的实现细节和代码结构,我已将项目代码上传至Gitee平台。如果你对项目有任何疑问,或者想要下载代码进行学习,都可以前往Gitee进行查看和下载。同时,我也非常期待你的反馈和建议,若是你有任何好的思路或想法,欢迎在Gitee、评论区、私信等方式与我进行探讨和交流。

感谢你的阅读、点赞和关注,希望你在Express框架的学习道路上越走越远,不断取得新的进步!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值