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

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测试
    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}`);
});
  • 问题:为什么使用路由模块需要将用户相关路由挂载到 /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]);
  });
};

两种方式的总结

  1. 路径参数(推荐):

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/938350.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

arXiv-2024 | NavAgent:基于多尺度城市街道视图融合的无人机视觉语言导航

作者:Youzhi Liu, Fanglong Yao*, Yuanchang Yue, Guangluan Xu, Xian Sun, Kun Fu 单位:中国科学院大学电子电气与通信工程学院,中国科学院空天信息创新研究院网络信息系统技术重点实验室 原文链接:NavAgent: Multi-scale Urba…

易语言鼠标轨迹算法(游戏防检测算法)

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…

Three.js材质纹理扩散过渡

Three.js材质纹理扩散过渡 import * as THREE from "three"; import { ThreeHelper } from "/src/ThreeHelper"; import { LoadGLTF, MethodBaseSceneSet } from "/src/ThreeHelper/decorators"; import { MainScreen } from "/src/compone…

apache-tomcat-6.0.44.exe Win10

apache-tomcat-6.0.44.exe Win10

赫布定律 | 机器学习 / 反向传播 / 经验 / 习惯

注:本文为 “赫布定律” 相关文章合辑。 未整理。 赫布定律 Hebb‘s law 馥墨轩 2021 年 03 月 13 日 00:03 1 赫布集合的基本定义 唐纳德・赫布(Donald Hebb)在 1949 年出版了《行为的组织》(The Organization of Behavior&a…

uni-app实现小程序、H5图片轮播预览、双指缩放、双击放大、单击还原、滑动切换功能

前言 这次的标题有点长,主要是想要表述的功能点有点多; 简单做一下需求描述 产品要求在商品详情页的头部轮播图部分,可以单击预览大图,同时在预览界面可以双指放大缩小图片并且可以移动查看图片,双击放大&#xff0…

杭州乘云联合信通院发布《云计算智能化可观测性能力成熟度模型》

原文地址:杭州乘云联合中国信通院等单位正式发布《云计算智能化可观测性能力成熟度模型》标准 2024年12月3日,由全球数字经济大会组委会主办、中国信通院承办的 2024全球数字经济大会 云AI计算创新发展大会(2024 Cloud AI Compute Ignite&…

第6章图6.21-6.27-《分析模式》原图和UML图对比

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集

如何在谷歌浏览器中设置广告屏蔽

在数字时代,网络广告无处不在,虽然它们为网站提供了收入来源,但有时也会干扰我们的浏览体验。如果你正在寻找一种方法来减少这些干扰,那么在谷歌浏览器中设置广告屏蔽是一个不错的选择。本文将指导你完成这一过程,并简…

认识网络互联设备(二)

交换机 功能: (1)通过支持并行通信,提高交换机的信息吞吐量; (2)将传统的一个大局域网上的用户分若干工作组,每个端口连接一台设备或者连接一个工作组,有效的解决了拥塞情…

数据可视化-2. 条形图

目录 1. 条形图适用场景分析 1.1 比较不同类别的数据 1.2 展示数据分布 1.3 强调特定数据点 1.4 展示时间序列数据的对比 1.5 数据可视化教育 1.6 特定领域的应用 2. 条形图局限性 3. 条形图图代码实现 3.1 Python 源代码 3.2 条形图效果(网页显示&#…

AMBA-CHI协议详解(十二)

AMBA-CHI协议详解(一)- Introduction AMBA-CHI协议详解(二)- Channel fields / Read transactions AMBA-CHI协议详解(三)- Write transactions AMBA-CHI协议详解(四)- Other transac…

【MATLAB第109期】基于MATLAB的带置信区间的RSA区域敏感性分析方法,无目标函数

【MATLAB第108期】基于MATLAB的带置信区间的RSA区域敏感性分析方法,无目标函数 参考第64期文章【MATLAB第64期】【保姆级教程】基于MATLAB的SOBOL全局敏感性分析模型运用(含无目标函数,考虑代理模型) 创新点: 1、采…

《外国服务区加油站模型:功能与美观的完美结合 caotu66.com》

这个外国服务区加油站模型在设计上独具特色,兼具实用性和美观性。 从整体布局来看,加油站位于服务区的显眼位置。加油站的顶棚采用了现代风格的设计,顶棚的颜色主要是黄色和蓝色,色彩鲜明且具有辨识度。顶棚下方有多个加油柱&…

mybatis-plus超详细讲解

mybatis-plus (简化代码神器) 地址:https://mp.baomidou.com/ 目录 mybatis-plus 简介 特性 支持数据库 参与贡献 快速指南 1、创建数据库 mybatis_plus 2、导入相关的依赖 3、创建对应的文件夹 4、编写配置文件 5、编写代码 …

数据结构(顺序表)JAVA方法的介绍

前言 在 Java 中,集合类(Collections)是构建高效程序的核心组件之一,而 List 接口作为集合框架中的重要一员,是一个有序、可重复的元素集合。与 Set 接口不同,List 保证了元素的顺序性,并允许存…

泊松编辑 possion editing图像合成笔记

开源地址: GitHub - kono-dada/Reproduction-of-possion-image-editing 掩码必须是矩形框

【Flink-scala】DataStream编程模型之状态编程

DataStream编程模型之状态编程 参考: 1.【Flink-Scala】DataStream编程模型之数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 3.【Flink-scala】DataStream编程模型之窗口计算-触发器-驱逐器 4.【Flink-scal…

Linux实操篇-远程登录/Vim/开机重启

目录 传送门前言一、远程登录1、概念2、ifconfig3、实战3.1、SSH(Secure Shell)3.2、VNC(Virtual Network Computing)3.3、RDP(Remote Desktop Protocol)3.4、Telnet(不推荐)3.5、FT…

【计算机网络】期末考试预习复习|上

作业讲解 物理层作业 共有4个用户进行CDMA通信。这4个用户的码片序列为: A: (–1 –1 –1 1 1 –1 1 1);B: (–1 –1 1 –1 1 1 1 –1) C: (–1 1 –1 1 1 1 –1 –1);D: (–1 1 –1 –1 –1 –1 1 –1) 现收到码片序列:(–1 1 –…