Node的学习
- Node的基础
- 上述是关于Node的一些基础,总结的还行;
利用Node书写接口并操作数据库
1. 初始化项目
- 创建新的项目文件夹,并初始化 package.json
mkdir my-backend
cd my-backend
npm init -y
2. 安装必要的依赖
- 安装Express.js(用于处理http请求)
npm install express
- 安装CORS,支持跨域请求
npm install cors
- 安装nodemon,使用开发模式(自动重启服务); s
npm install --save-dev nodemon
3. 创建主程序文件index.js
- 目前是绝大多数逻辑都写在了主程序文件index.js中,后续会将里面绝大部分内容抽离开来,比如路由信息、中间件、控制器等;
const db = require('./db');
// 有几个常用的操作路径的方式需要注意;
// 引入必要模块
const express = require('express');
const cors = require('cors');
const app = express(); // 创建 Express 应用实例
const PORT = 3000; // 设置服务端口
// 中间件配置
app.use(cors()); // 允许跨域
app.use(express.json()); // 解析 JSON 格式的请求体
app.use(express.urlencoded({ extended: true })); // 解析 URL 编码的请求体
// 路由
app.get('/', (req, res) => {
res.send('Hello, World! Welcome to the Node.js backend!');
});
app.post('/data', (req, res) => {
const { name, age } = req.body; // 从请求体中获取数据
res.json({ message: `Received data for ${name}, age ${age}` });
});
/**
* 扩展功能:1. 增加更多路由;或者说查询路由
*/
app.get('/users', (req, res) => {
db.query('SELECT * FROM users', (err, results) => {
if (err) {
res.status(500).json({ error: 'Database query failed' });
return;
}
res.json(results);
});
});
// 2. 插入用户数据
app.post('/addUser', (req, res) => {
//
const { id, username, password } = req.body;
db.query('INSERT INTO users (id, username, password) VALUES (?, ?, ?)', [id, username, password], (err, result) => {
if (err) {
res.status(500).json({ error: 'Failed to insert user' });
return;
}
res.json({ message: 'User created successfully', userId: result.insertId });
});
})
// post请求一般都会解析用户数据;
app.post('/users', (req, res) => {
const { name } = req.body;
res.json({ message: `User ${name} created successfully!` });
});
// 启动服务
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
4. 主程序中连接数据库操作
- 安装数据库
npm install mongoose # MongoDB
npm install mysql2 # MySQL
- 连接数据库 db.js
const mysql = require('mysql2');
// 创建数据库连接
const db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '123456',
database: 'my_db_01'
});
// 连接数据库
db.connect((err) => {
if (err) {
console.error('Error connecting to the database:', err);
return;
}
console.log('Connected to MySQL database.');
});
module.exports = db; // 导出数据库连接实例
5. 运行服务器
npx nodemon index.js
- 结果图
6. 测试
get接口方法测试
- 在浏览器测试; 输入:http://localhost:3000/users
- postman测试
post接口方法测试
- 在发送请求以后,即可在数据库中查看到新添加的数据
Node项目的规范化
- 上面的Node项目已经可以完成一个较为试水的项目了,但是项目结构需要优化下:
路由模块写法
- 将原先写在app.js(index.js)中的路由信息分开写,分为users.js和students.js
- 以users.js为例,其路由信息的js书写如下:
// 用户路由
const express = require('express');
const router = express.Router();
const db = require('../db'); // 引入数据库配置信息
// 获取所有用户数据
router.get('/users', (req, res) => {
db.query('SELECT * FROM users', (err, results) => {
if (err) {
res.status(500).json({ error: 'Database query failed' });
return;
}
res.json(results);
});
});
// 添加用户信息
router.post('/addUser', (req, res) => {
const { id, username, password } = req.body;
db.query('INSERT INTO users (id, username, password) VALUES (?, ?, ?)', [id, username, password], (err, result) => {
if (err) {
res.status(500).json({ error: 'Failed to insert user' });
return;
}
res.json({ message: 'User created successfully', userId: result.insertId });
});
})
module.exports = router;
- 添加到app.js的路由书写如下:
// app.js 作为入口文件;
const express = require('express');
const cors = require('cors');
const userRoutes = require('./routes/users'); // 引入用户路由
const studentsRoutes = require('./routes/students'); // 引入学生路由
const app = express();
const PORT = 3000;
// 中间件配置
app.use(cors()); // 允许跨域
app.use(express.json()); // 处理JSON格式
app.use(express.urlencoded({ extended: true })); // 处理URL编码
// 基础路由
app.get('/', (req, res) => {
res.send('Hello, World! Welcome to the Node.js backend!');
});
// 使用路由模块
app.use('/api', userRoutes); // 将用户相关路由挂载到/api中;
app.use('/api', studentsRoutes);
// 启动服务
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
- 问题:为什么使用路由模块需要将用户相关路由挂载到 /apo中,而不是直接/ 呢
- RESTful风格标准(现代web开发的一种标准)
- 防止命名冲突,如果项目中没有统一前缀,路由很容易与其他资源冲突
- 前端调用时的统一管理,有利于集中管理API
控制器写法
- 其实控制器就是在路由的基础上进一步优化,这一点非常关键;
- 具体见操作数据库的代码
路径参数和查询参数的比较
- 路径参数 和 查询参数 是两种不同的传参方式,需要在路由定义和请求中保持一致。
路径参数
- 路径参数:通过id查询
router.get('/getStudentsById/:id', getStudentById);
- Postman 请求示例
GET http://localhost:3000/api/getStudentsById/101
const getStudentById = (req, res) => {
console.log('req.params', req.params);
const { id } = req.params; // 从路径参数中获取 id
console.log('我已经获取到了id是', id);
db.query('SELECT * FROM student WHERE id = ?', [id], (err, results) => {
if (err) {
res.status(500).json({ error: 'Database query failed' });
return;
}
if (results.length === 0) {
return res.status(404).json({ message: 'Student not found' });
}
res.json(results[0]);
});
};
查询参数
- 如果想通过
?id=101
这样的查询参数传值,那么需要修改控制器中的代码,从req.query
中获取参数。 - 路由定义:
router.get('/getStudentsById', getStudentById); // 无需路径参数
- Postman 请求示例:
GET http://localhost:3000/api/getStudentsById?id=101
- 控制器代码修改:
const getStudentById = (req, res) => {
console.log('req.query', req.query);
const { id } = req.query; // 从查询参数中获取 id
console.log('我已经获取到了id是', id);
if (!id) {
return res.status(400).json({ error: 'Student ID is required' });
}
db.query('SELECT * FROM student WHERE id = ?', [id], (err, results) => {
if (err) {
res.status(500).json({ error: 'Database query failed' });
return;
}
if (results.length === 0) {
return res.status(404).json({ message: 'Student not found' });
}
res.json(results[0]);
});
};
两种方式的总结
-
路径参数(推荐):
- URL 格式:
/getStudentsById/:id
- 请求示例:
GET /api/getStudentsById/101
- 后端通过
req.params
获取参数。
- URL 格式:
-
查询参数:
- URL 格式:
/getStudentsById?id=101
- 请求示例:
GET /api/getStudentsById?id=101
- 后端通过
req.query
获取参数
- URL 格式:
总结:使用 路径参数 更符合 RESTful 风格,代码更语义化。