所有文章 > API开发 > 使用Node.js、Express和MySQL构建REST API
使用Node.js、Express和MySQL构建REST API

使用Node.js、Express和MySQL构建REST API

编者按:本文最近一次由 Ikeh Akinyemi 于 2024 年 10 月 21 日更新,介绍了高级 MySQL 查询技术,如多表联接、全文搜索和事务管理。

要在Node.js中使用MySQL,你需要将MySQL驱动程序集成到你的Node.js应用程序中。最流行且可靠的选择是一个提供基于回调和基于Promise接口的包,用于执行MySQL查询。以下是一个在Node.js中连接和查询MySQL数据库的快速示例:mysql2

const mysql = require('mysql2/promise');
async function connectToDatabase() {
try {
const connection = await mysql.createConnection({
host
: 'localhost',
user
: 'your_username',
password
: 'your_password',
database
: 'your_database'
});

// Execute a simple query
const [rows, fields] = await connection.execute('SELECT * FROM users');
console
.log('Query results:', rows);

await connection.end();
} catch (error) {
console
.error('Database connection failed:', error);
}
}

在为您的 Node.js 应用程序选择数据库时,您有几个很好的选择。虽然 MongoDB 通常与 MEAN/MERN 堆栈中的 Node.js 相关联,但 MySQL、PostgreSQL 和 SQLite 等关系数据库同样是强大的选择。MySQL 因其功能集、广泛的社区支持以及Node.js整体式和微服务应用程序的卓越性能而脱颖而出,尤其是在处理结构化数据或在现有 MySQL 基础设施上构建时。

在本教程中,我们将学习如何使用 MySQL 作为数据库构建完整的 REST API,并使用 Express.js 框架进行Node.js。我们的示例 API 将跟踪流行的编程语言,演示数据建模、CRUD 操作和正确的 API 设计等关键概念。

使用 Node.js、Express 和 MySQL 构建 REST API

先决条件

要阅读本文,您应该具备以下条件:

本教程中的代码在安装了 Node 14 LTS 的 Mac 上执行。您可以使用 Node.jsDocker 和 Docker Compose 来改善您的开发人员体验。您还可以在此 GitHub 存储库中访问完整代码。现在,让我们开始吧!

什么是 MySQL?

MySQL 是一个功能丰富的关系数据库,于 1995 年首次发布。它可以在所有主要操作系统上运行,如 Linux、Windows 和 macOS。

MySQL 是全球最受欢迎的数据库之一。根据 2023 年 Stack Overflow 调查,MySQL 是最受欢迎的数据库,超过 41% 的受访者使用它。社区版是免费提供的,并且得到了一个大型活跃社区的支持。

由于其功能和成本效益,MySQL 被大型企业和新初创公司使用。对于我们的示例 REST API,我们将使用免费的 MySQL 服务,而不是设置本地 MySQL 服务器。

设置我们的 MySQL 数据库

为了托管我们的测试 MySQL 8.0 数据库,我们将使用 db4free.net。首先,转到 db4free 注册页面,然后通过选择您的数据库名称和用户名来填写所需的详细信息:

Db4free 注册页

单击 Signup(注册),您应该会收到一封确认电子邮件。通过电子邮件确认您的帐户。接下来,在侧边栏上,单击 phpMyAdmin。在 phpMyAdmin 登录名中,输入您选择的用户名和密码,然后单击 Go

Db3free 注册选项

现在,我们有一个空的数据库。让我们添加表格。首先,单击左侧的数据库名称;对我来说,它是 restapitest123。然后,单击顶部菜单上的 SQL,并将以下代码放入文本区域:programming_languagesCREATE TABLE

CREATE TABLE `programming_languages`
(
`id` INT(11) NOT NULL auto_increment ,
`name` VARCHAR(255) NOT NULL ,
`released_year` INT NOT NULL ,
`githut_rank` INT NULL ,
`pypl_rank` INT NULL ,
`tiobe_rank` INT NULL ,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`updated_at` DATETIME on UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
PRIMARY KEY
(`id`),
UNIQUE
`idx_name_unique` (`name`(255))
)
engine
= innodb charset=utf8mb4 COLLATE utf8mb4_general_ci;

单击 Go 按钮,如下所示:

创建编程语言表

该代码将返回一个绿色复选框和一条带有 .这样,我们创建了一个名为 的表,其中包含 8 列和一个名为 的主键,该主键是 Internet 和自动递增的。MySQL returned an empty result set (i.e. zero rows)programming_languagesid

该列是唯一的,我们还为编程语言添加了该列。我们有三列来输入编程语言的排名,这些排名来自以下资源:namereleased_year

  • GitHut:2020 年第 4 季度 GitHub 语言统计数据
  • PYPL:编程语言的流行度指数
  • TIOBE 指数

和 列存储日期以跟踪行的创建和更新时间。created_atupdated_at

为编程语言添加 demo 行

接下来,我们将向表中添加 16 种流行的编程语言。单击页面顶部的相同 SQL 链接,然后复制并粘贴以下代码:programming_languages

INSERT INTO programming_languages(id,name,released_year,githut_rank,pypl_rank,tiobe_rank) 
VALUES 
(1,'JavaScript',1995,1,3,7),
(2,'Python',1991,2,1,3),
(3,'Java',1995,3,2,2),
(4,'TypeScript',2012,7,10,42),
(5,'C#',2000,9,4,5),
(6,'PHP',1995,8,6,8),
(7,'C++',1985,5,5,4),
(8,'C',1972,10,5,1),
(9,'Ruby',1995,6,15,15),
(10,'R',1993,33,7,9),
(11,'Objective-C',1984,18,8,18),
(12,'Swift',2015,16,9,13),
(13,'Kotlin',2011,15,12,40),
(14,'Go',2009,4,13,14),
(15,'Rust',2010,14,16,26),
(16,'Scala',2004,11,17,34);

您应该会收到一条类似 “16 rows inserted” 的消息。然后,通过语句收集来自三个来源的数据并将其添加到表中,创建 16 行,每种编程语言一行。当我们获取 API 端点的数据时,我们将返回此内容。
如果我们单击左侧可见的 programming_languages 表,我们将看到刚刚添加的行:INSERTGET

添加了行的编程语言表

接下来,我们将使用 Node.js 和 MySQL 为 REST API 设置 Express.js。

什么是 REST API?

REST API,即Representational State Transfer API的简称,是一种流行的用于设计Web服务和API的架构风格。REST API通过标准的HTTP方法(如GET、POST、PUT和DELETE)实现客户端与服务器之间的通信,遵循无状态和资源交互的原则。

REST API 的一些重要准则包括:

  • 客户端-服务器架构:REST API 分为客户端和服务器组件,允许它们独立发展
  • Statelessness(无状态):客户端请求包含理解和满足请求所需的所有信息。服务器在请求之间不存储任何客户端状态
  • 可缓存性:REST API 可以利用缓存机制来提高性能并减少服务器上的负载
  • 统一接口:REST API 具有一致且统一的接口,包括使用标准 HTTP 方法(GET、POST、PUT、DELETE)对资源执行操作

为我们的 REST API 设置 Express.js

要使用 Express.js 服务器设置 Node.js 应用程序,我们首先要为项目创建一个目录:mkdir programming-languages-api && cd programming-languages-api

然后,我们可以创建一个文件,如下所示:package.jsonnpm init -y

{
  "name": "programming-languages-api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}

要安装 Express,我们将运行 ,在文件中添加 Express 作为依赖项。接下来,我们将在文件中创建一个 slim 服务器。它将在主路径上打印一条消息:npm i expresspackage.jsonindex.jsok/

const express = require("express");
const app = express();
const port = 3000;
app
.use(express.json());
app
.use(
express
.urlencoded({
extended
: true,
})
);
app
.get("/", (req, res) => {
res
.json({ message: "ok" });
});
app
.listen(port, () => {
console
.log(`Example app listening at http://localhost:${port}`);
});

在上面的代码中,有几点需要注意。首先,在接下来的步骤中,我们将使用内置的 Express JSON 解析器中间件来解析 JSON。我们还将使用中间件来解析 URL 编码的正文。express.urlencoded()

如果未作为环境变量提供,我们的应用程序将在端口号 3000 上运行。我们可以运行服务器,并点击查看输出。PORTnode index.jshttp://localhost:3000{message: "ok"}

REST API 项目结构

我们将按以下方式构建我们的项目,以将文件逻辑地排列在文件夹中:

节点项目文件夹结构布局

config.js将包含数据库凭证和我们在对结果进行分页时要每页显示的行等信息的配置。 是任何辅助函数的主目录,例如计算分页的偏移量。helper.js

该文件将成为 URI 和服务中相应函数之间的粘附。该文件夹将包含我们所有的服务。其中之一是 ,我们用它来与 MySQL 数据库通信。routes/programmingLanguages.jsservices/programmingLanguages.jsservicesdb.js

另一个服务是 ,它将具有 、 等方法,用于获取和创建编程语言资源。URI 和相关服务函数的基本映射将类似于以下代码:programmingLanguages.jsgetMultiplecreateGET /programming-languages → getMultiple() POST /programming-languages → create() PUT /programming-languages/:id → update() DELETE /programming-languages/:id → remove()

现在,让我们使用分页对编程语言 API 进行编码。GET

GET流行的编程语言

我们需要将 Node.js 服务器与 MySQL 链接,以创建我们的 GET 编程语言 API。我们将使用该包与 MySQL 数据库进行交互。mysql2

首先,我们需要在项目根目录下使用以下命令进行安装:mysql2

npm i mysql2

接下来,我们将在项目的根目录下创建包含以下内容的文件:config

const config = {
  db: {
/* don't expose password or any sensitive info, done only for demo */
host
: "db4free.net",
user
: "restapitest123",
password
: "restapitest123",
database
: "restapitest123",
connectTimeout
: 60000
},
listPerPage
: 10,
};
module
.exports = config;

值得注意的是,我们将 设置为 60 秒。默认值为 10 秒,这可能还不够。因此,我们将使用以下代码创建文件:connectTimeouthelper.js

function getOffset(currentPage = 1, listPerPage) {
  return (currentPage - 1) * [listPerPage];
}

function emptyOrRows(rows) {
if (!rows) {
return [];
}
return rows;
}

module
.exports = {
getOffset
,
emptyOrRows
}

对于有趣的部分,我们将添加路由并将其链接到服务。首先,我们将连接到数据库,并在文件中的数据库上启用运行查询:services/db.js

const mysql = require('mysql2/promise');
const config = require('../config');

async function query(sql, params) {
const connection = await mysql.createConnection(config.db);
const [results, ] = await connection.execute(sql, params);

return results;
}

module
.exports = {
query
}

之后,我们将在 中创建文件,如下所示:routesroutes/programmingLanguages.js

const express = require('express');
const router = express.Router();
const programmingLanguages = require('../services/programmingLanguages');

/* GET programming languages. */
router
.get('/', async function(req, res, next) {
try {
res
.json(await programmingLanguages.getMultiple(req.query.page));
} catch (err) {
console
.error(`Error while getting programming languages `, err.message);
next
(err);
}
});

module
.exports = router;

对于端点的最后一部分,我们需要在文件中连接路由,如下所示:GETindex.js

const express = require("express");
const app = express();
const port = 3000;
const programmingLanguagesRouter = require("./routes/programmingLanguages");
app
.use(express.json());
app
.use(
express
.urlencoded({
extended
: true,
})
);
app
.get("/", (req, res) => {
res
.json({ message: "ok" });
});
app
.use("/programming-languages", programmingLanguagesRouter);
/* Error handler middleware */
app
.use((err, req, res, next) => {
const statusCode = err.statusCode || 500;
console
.error(err.message, err.stack);
res
.status(statusCode).json({ message: err.message });
return;
});
app
.listen(port, () => {
console
.log(`Example app listening at http://localhost:${port}`);
});

我们对入口点文件进行了两项重要更改。首先,我们添加了以下代码:index.js

const programmingLanguagesRouter = require('./routes/programmingLanguages');

然后,我们将路由链接到我们刚刚创建的路由器:/programming-languages

app.use('/programming-languages', programmingLanguagesRouter);

我们还添加了错误处理程序中间件来处理错误并提供适当的状态代码和消息。添加端点后,当我们再次运行我们的应用程序并使用 点击浏览器时,我们将看到如下输出:GETnode index.jshttp://localhost:3000/programming-languages

GET 终端节点索引输出

根据您在浏览器上安装的扩展,您的输出可能看起来略有不同。请注意,我们已经为 API 实现了分页,这是可能的,因为 中的函数以及我们在 中运行查询的方式。尝试查看语言 11-16。GETgetOffsethelper.jsSELECTservices/programmingLanguage.jshttp://localhost:3000/programming-languages?page=2

POST一种新的编程语言

我们的 API 将允许我们在表中创建新的编程语言。要在终端节点中创建编程语言 API,我们将向 和 文件添加代码。在 service 方法中,我们将从请求正文中获取 name、release year 和其他排名,然后将它们插入到表中。POSTPOST/programming-languagesserviceroutesprogramming_languages

将以下代码附加到文件中:services/programmingLanguages.js

async function create(programmingLanguage){
  const result = await db.query(
`INSERT INTO programming_languages
(name, released_year, githut_rank, pypl_rank, tiobe_rank)
VALUES
('${programmingLanguage.name}', ${programmingLanguage.released_year}, ${programmingLanguage.githut_rank}, ${programmingLanguage.pypl_rank}, ${programmingLanguage.tiobe_rank})`
);

let message = 'Error in creating programming language';

if (result.affectedRows) {
message
= 'Programming language created successfully';
}

return {message};
}

请确保还导出以下函数:

module.exports = {
  getMultiple,
create
}

为了使上述函数可访问,我们需要添加一个路由以在文件中链接它:routes/programmingLanguages.js

/* POST programming language */
router.post('/', async function(req, res, next) {
try {
res
.json(await programmingLanguages.create(req.body));
} catch (err) {
console
.error(`Error while creating programming language`, err.message);
next
(err);
}
});

PUT更新现有编程语言

我们将使用终端节点更新现有编程语言,我们将在其中获取数据以更新语言。要更新编程语言,我们将根据请求中获得的数据运行查询。/programming-languages/:idUPDATE

PUT是一个幂等操作,这意味着如果一次又一次地进行相同的调用,它将产生相同的结果。要启用更新现有记录,我们将向编程语言服务添加以下代码:

async function update(id, programmingLanguage){
  const result = await db.query(
`UPDATE programming_languages
SET name
="${programmingLanguage.name}", released_year=${programmingLanguage.released_year}, githut_rank=${programmingLanguage.githut_rank},
pypl_rank
=${programmingLanguage.pypl_rank}, tiobe_rank=${programmingLanguage.tiobe_rank}
WHERE id
=${id}`
);

let message = 'Error in updating programming language';

if (result.affectedRows) {
message
= 'Programming language updated successfully';
}

return {message};
}

确保你也导出了这个函数,就像我们之前所做的那样:

module.exports = {
  getMultiple,
create
,
update
,
};

为了将代码与端点连接起来,我们将下面的代码添加到上面的编程语言路由文件中:PUTmodule.exports = router;

/* PUT programming language */
router.put('/:id', async function(req, res, next) {
try {
res
.json(await programmingLanguages.update(req.params.id, req.body));
} catch (err) {
console
.error(`Error while updating programming language`, err.message);
next
(err);
}
});

现在,我们可以更新任何现有的编程语言。例如,如果我们看到拼写错误,我们可以更新语言的名称。

DELETE一种编程语言

我们将使用带有 HTTP 方法的路径来添加删除编程语言的功能。继续运行以下代码:/programming-languages/:idDELETE

async function remove(id){
  const result = await db.query(
`DELETE FROM programming_languages WHERE id=${id}`
);

let message = 'Error in deleting programming language';

if (result.affectedRows) {
message
= 'Programming language deleted successfully';
}

return {message};
}

不要忘记导出此函数。再次,为了将服务与路由链接起来,我们将以下代码添加到文件中:routes/programmingLanguages.js

/* DELETE programming language */
router.delete('/:id', async function(req, res, next) {
try {
res
.json(await programmingLanguages.remove(req.params.id));
} catch (err) {
console
.error(`Error while deleting programming language`, err.message);
next
(err);
}
});

测试我们的 API

使用 运行 Node.js Express 服务器后,您可以测试所有 API 端点。要创建新的编程语言,让我们使用 Dart,并运行以下 cURL 命令。或者,您可以使用 Postman 或任何其他 HTTP 客户端:node index.js

curl -i -X POST -H 'Accept: application/json' \
    -H 'Content-type: application/json' http://localhost:3000/programming-languages \
--data '{"name":"dart", "released_year": 2011, "githut_rank": 13, "pypl_rank": 20, "tiobe_rank": 25}'

上面的代码将产生以下输出:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 55
ETag: W/"37-3mETlnRrtfrms6wlAjdgAXKq9GE"
Date: Mon, 01 Feb 2021 11:20:07 GMT
Connection: keep-alive

{"message":"Programming language created successfully"}

您可以使用 Express.js Helmet 删除 Header 并添加其他安全响应 Header,这将大大提高 API 的安全性。现在,让我们将 GitHut 排名从 13 更新到 12:X-Powered-ByDart

curl -i -X PUT -H 'Accept: application/json' \
    -H 'Content-type: application/json' http://localhost:3000/programming-languages/17 \
--data '{"name":"dart", "released_year": 2011, "githut_rank": 12, "pypl_rank": 20, "tiobe_rank": 25}'

上面的代码将生成如下所示的输出:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 55
ETag: W/"37-0QPAQsRHsm23S9CNV3rPa+AFuXo"
Date: Mon, 01 Feb 2021 11:40:03 GMT
Connection: keep-alive

{"message":"Programming language updated successfully"}

要测试 API,你可以使用以下 cURL 删除 Dart:DELETEID 17

curl -i -X DELETE -H 'Accept: application/json' \
    -H 'Content-type: application/json' http://localhost:3000/programming-languages/17

上面的代码将产生以下输出:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 55
ETag: W/"37-aMzd+8NpWQ09igvHbNLorsXxGFo"
Date: Mon, 01 Feb 2021 11:50:17 GMT
Connection: keep-alive

{"message":"Programming language deleted successfully"}

如果您更习惯于使用可视化界面进行测试,例如 Postman,则可以将 cURL 命令导入到 Postman 中。

在本教程中,我们使示例相当简单。但是,如果这是一个真实的 API,而不是一个演示,我强烈推荐以下内容:

  • 使用像 Joi 这样的健壮验证库来精确验证输入,例如,确保编程语言的名称是必需的。它已存在于数据库中
  • 通过向 Express.js 添加Helmet.js来提高安全性
  • 使用像 Winston 这样的 Node.js 日志库,以更易于管理的方式简化日志
  • 将 Docker 用于 Node.js 应用程序

高级示例:使用 store 过程

在本教程中,为了简化操作,我们使用了内联SQL语句。但在实际项目中,我们应该考虑使用存储过程。使用存储过程代替内联SQL具有多个优势:性能提升、更易维护,更重要的是,安全性更高。

让我们在应用程序中添加新路由以使用 store 过程。首先,我们需要在数据库中创建它。运行以下 SQL 脚本,创建按 ID 搜索编程语言的存储过程:GET/programming-languages/:id

DELIMITER $$
CREATE PROCEDURE `sp_search_programming_languages_by_id`(in langid int)
BEGIN
SELECT name
, githut_rank, pypl_rank, tiobe_rank, created_at
FROM programming_languages
where id = langid;
END $$

要使用新创建的 store 过程,我们需要将此设置添加到 :config.js

const config = {
    db: {
...
multipleStatements
: true
},

然后,我们可以向 :db.js

async function callSpSearch(id) {
    const connection = await mysql.createConnection(config.db);
const [results, ] = await connection.query('CALL sp_search_programming_languages_by_id(' + id + ')');

return results;
}

新函数也需要导出:

module.exports = {
  query,
callSpSearch
}

接下来,将此函数添加到 中,并将其添加到导出中:services/programmingLanguages.js

async function search(id){
  const rows = await db.callSpSearch(id);
const data = helper.emptyOrRows(rows);
return {
data
}
}

module
.exports = {
getMultiple
,
create
,
update
,
remove
,
search
}

最后一步是将新路由添加到 :routes/programmingLanguages.js

router.get('/:id', async function(req, res, next) {
    try {
res
.json(await programmingLanguages.search(req.params.id));
} catch (err) {
console
.error(`Error while searching programming languages `, err.message);
next
(err);
}
});

就是这样!现在,我们可以重新启动服务器并试一试。使用 进入浏览器,我们应该会看到类似于下面的输出:http://localhost:3000/programming-languages/1

localhost 代码输出

在此 CodeSandbox 编辑器中查看完整源代码。

让我们讨论一下在扩展 Node.js 应用程序时应考虑的更高级的 MySQL 查询技术。

多表联接

假设我们想要跟踪编程语言框架。我们可以创建一个相关表并使用 JOIN 操作:

async function getLanguageWithFrameworks(languageId) {
  const result = await db.query(`
SELECT l
.name as language, l.released_year,
f
.name as framework, f.release_date
FROM programming_languages l
LEFT JOIN frameworks f ON l
.id = f.language_id
WHERE l
.id = ?*,
[languageId]
);
return result;
}

全文搜索

在实现超越简单查询条件的搜索功能时,全文搜索是必不可少的。虽然基本查询可能适用于小型数据集,但全文搜索能为基于文本的搜索提供更好的性能和更相关的结果。MySQL 的全文搜索支持自然语言模式和布尔模式,允许复杂的搜索模式,包括短语匹配和单词排除:WHERELIKE

// First, add a FULLTEXT index
// ALTER TABLE programming_languages ADD FULLTEXT(name, description);

async function searchLanguages(searchTerm) {
const result = await db.query(`
SELECT name
, description,
MATCH
(name, description) AGAINST(?) as relevance
FROM programming_languages
WHERE MATCH
(name, description) AGAINST(?)
ORDER BY relevance DESC
`,
[searchTerm, searchTerm]
);
return result;
}

交易管理

在执行多个相关的数据库操作时,事务对于维护数据完整性至关重要。它们确保一系列查询要么全部成功,要么全部一起失败,从而防止可能导致数据库处于不一致状态的部分更新。在处理相关表或实现需要多个步骤才能完成的操作时,这一点尤为重要。

例如,在添加新的编程语言及其关联的框架时,我们希望确保 1) 该语言及其框架都已成功添加,或者 2) 根本没有添加。以下是我们如何使用交易来实现这一点:

async function addLanguageWithFrameworks(language, frameworks) {
  const connection = await mysql.createConnection(config.db);
try {
await connection.beginTransaction();

const [languageResult] = await connection.execute(
'INSERT INTO programming_languages (name, released_year) VALUES (?, ?)',
[language.name, language.released_year]
);

const languageId = languageResult.insertId;
for (const framework of frameworks) {
await connection.execute(
'INSERT INTO frameworks (language_id, name, release_date) VALUES (?, ?, ?)',
[languageId, framework.name, framework.release_date]
);
}

await connection.commit();
return { success: true, languageId };
} catch (error) {
await connection.rollback();
throw error;
} finally {
connection
.end();
}
}

为什么不直接使用 ORM 呢?

ORM(对象关系映射)是将面向对象的代码与关系数据库连接起来的库。它允许开发人员使用编程语言概念与数据库交互,而不是编写原始 SQL 查询。

虽然使用 ORM 有其优点,但与原版方法相比,它也有局限性和缺点:

  • ORM 在应用程序和数据库之间添加了一个额外的抽象层。在某些用例中,这可能会导致性能欠佳
  • 使用 ORM 可能会给应用程序带来很大的复杂性,并且开发人员可能需要相当长的学习曲线才能理解框架及其约定。对于小型项目,这些开销可能大于收益
  • ORM 设计为与数据库无关,可在多个不同的数据库之间提供一致的接口。这种抽象可能会导致某些特定于数据库的功能受到限制。如果我们的应用程序依赖于 ORM 不支持的某些特定于数据库的功能,那么 vanilla 方法将是一个更好的选择

总之,是否使用 ORM 取决于许多因素,包括应用程序要求、性能考虑、项目规模、复杂性和团队技能。

结论

我们构建了一个功能齐全的 REST API,展示了 Node.js 和 MySQL 的强大组合。从基本的数据库设置和 CRUD 操作开始,我们已经了解了 store 过程、事务管理和复杂的查询技术等高级概念。这种集成展示了为什么 MySQL 仍然是 Node.js 应用程序的强大选择,尤其是在处理结构化数据和复杂关系时。

请记住,在选择原始SQL查询、存储过程和对象关系映射(ORM)时,应根据您的具体用例、团队专长和性能要求来决定。Node.js与MySQL的灵活性使您能够选择最适合您需求的方法。

请记住,在原始 SQL 查询、存储过程和 ORM 之间进行选择应根据您的特定用例、团队专业知识和性能要求。Node.js 与 MySQL 的灵活性允许您选择最适合您需求的方法。

我希望你喜欢这篇文章。祝您编码愉快!

原文来源:https://blog.logrocket.com/build-rest-api-node-express-mysql/

#你可能也喜欢这些API文章!