Node的学习以及学习通过Node书写接口并简单操作数据库

embedded/2024/12/21 17:26:08/

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
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
  • 结果图
    表示成功连接上<a class=数据库" />

6. 测试

get接口方法测试
  • 在浏览器测试; 输入:http://localhost:3000/users
    在这里插入图片描述
  • postman测试
    postman测试结果图
post接口方法测试

在这里插入图片描述

  • 在发送请求以后,即可在数据库中查看到新添加的数据新添加的数据

Node项目的规范化

  • 上面的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}`);
});
  • 问题:为什么使用路由模块需要将用户相关路由挂载到 /api中,而不是直接/ 呢
    • 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; // 从路径参数中获取 idconsole.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; // 从查询参数中获取 idconsole.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]);});
};

两种方式的总结

  1. 路径参数(推荐):

    • URL 格式:/getStudentsById/:id
    • 请求示例:GET /api/getStudentsById/101
    • 后端通过 req.params 获取参数。
  2. 查询参数

    • URL 格式:/getStudentsById?id=101
    • 请求示例:GET /api/getStudentsById?id=101
    • 后端通过 req.query 获取参数

总结:使用 路径参数 更符合 RESTful 风格,代码更语义化。

控制器controllers;

  • 控制器controllers主要是用于处理逻辑业务;即可以将路由中后面那个函数统一抽取到控制器进行处理,用于解放路由函数;

中间件middlewares

  • 概念; 中间件常用于请求(req)和响应(res)之间进行处理;
  • 中间件可以拦截请求、进行逻辑处理、修改请求和响应、执行后续处理等操作;
  • 常见的中间件作用
    • 请求预处理;在请求到达路由之前对数据进行校验,解析,过滤等操作;
    • 权限控制与认证;
    • 日志记录;
    • 错误处理;
    • 响应数据封装;
    • 跨域处理;
    • 静态资源托管;

工具类函数 utils

  • 工具类文件夹;通常存放通用的工具类函数,这些工具函数可以在整个项目中复用;可以避免代码冗余,提升开发效率;
  • 工具类的常见用途(其实就是一些处理代码逻辑的公用的一些方法)
    • 加密与解密工具:密码加密、Token 签发验证等。
    • 日期与时间处理:格式化日期、计算时间差等。
    • 数据格式化工具:字符串转换、数字格式化等。
    • 随机数与唯一 ID 生成:生成唯一标识符或验证码。
    • 请求数据处理:深度克隆、对象合并、数据校验。
    • 日志处理:封装日志记录方法。
    • 响应格式封装:统一格式化接口的响应数据。
    • 文件操作工具:上传、下载、路径处理等。

http://www.ppmy.cn/embedded/147581.html

相关文章

使用 esrally race 测试 Elasticsearch 性能:实践指南

在 Elasticsearch 性能优化和容量规划中&#xff0c;使用 esrally 进行基准测试是官方推荐的方式。通过 esrally race 命令&#xff0c;您可以针对不同的数据集与挑战类型&#xff0c;对 Elasticsearch 集群进行精确的性能评估。本文将简要介绍常用的数据集与挑战类型&#xff…

【mac 终端美化】oh my zsh

快捷的mac终端美化方法。 以下是效果图&#xff0c;比较朴素&#xff0c;但是相比默认方案会好看一些&#xff0c;也能明显查看输入的命令&#xff0c;不会和输出混在一起。 下载主题 访问网址&#xff1a;https://iterm2colorschemes.com/&#xff0c;下载网页的压缩包并解…

Python从0到100(七十八):神经网络--从0开始搭建全连接网络和CNN网络

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

软件项目开发中,需求分析所占比例一般是多少?

在软件项目开发中&#xff0c;需求分析阶段通常占整个项目开发周期的较大比例。具体比例可能会因项目的复杂性、规模、行业和开发方法&#xff08;如瀑布模型、敏捷开发等&#xff09;而有所不同。一般来说&#xff0c;需求分析的时间和资源投入占比大致在 10% 到 20% 之间&…

谷歌浏览器的多语言支持与设置教程

在当今全球化的时代&#xff0c;拥有一款能够提供多语言支持的浏览器变得尤为重要。谷歌浏览器作为全球最受欢迎的浏览器之一&#xff0c;其强大的多语言支持和简便的设置方法&#xff0c;为用户提供了极大的便利。本文将详细介绍如何在谷歌浏览器中进行语言设置、消息推送以及…

VSCode如何修改默认扩展路径和用户文件夹目录到D盘

在使用Visual Studio Code&#xff08;VSCode&#xff09;时&#xff0c;随着安装的扩展和用户数据的增多&#xff0c;C盘的空间可能会逐渐紧张。为了优化存储管理&#xff0c;将VSCode的默认扩展路径和用户文件夹目录迁移到D盘是一个有效的解决方案。以下是详细的操作步骤&…

C语言基础(五)【控制语句与循环综合应用篇猜数字游戏】

文章目录 前言一、实现一个猜数字游戏二、游戏实现的步骤1. 随机数生成1.1 rand1.2 srand1.3 time1.4 设置随机数的范围 2. 菜单函数的实现 3. 游戏函数的实现 二、猜数字游戏的实现1. 不限制次数 2. 限制次数为 5 总结 前言 学习过前面有关控制语句跟循环的相关知识&#xf…

系统设计:微服务架构的可扩展性系统 详解

在本文中&#xff0c;我们将设计一个基于微服务架构的可扩展系统。我将详细解释每个设计步骤的底层原理&#xff0c;并清晰推导每个决策背后的原因&#xff0c;以便让新同志们能够清楚理解为什么这样设计以及如何实现。 一、可扩展系统的核心需求 在设计一个可扩展性系统时&am…