首页 > 其他分享 >express的使用笔记 2 请求对象与响应对象 、 增删改查demo

express的使用笔记 2 请求对象与响应对象 、 增删改查demo

时间:2024-10-11 17:12:19浏览次数:9  
标签:req const demo express 改查 send db res todos

Express不对Node.js已有的特性进行二次抽象,只是在它之上扩展了web应用所需的基本功能。内部使用的依旧是http模块,请求对象继承字http.IncomingMessage,响应对象继承自http.ServerResponse,所以node.js官网中的对应的方法可以通用

1.请求对象

2.响应对象
除了response.send(),response.write()也可以发送数据
也可以直接在结束响应的同时发送数据response.send(1)


路由设计Demo练习:
需求描述:实现对任务清单的CRUD接口服务
·查询任务列表 ---》GET/todos
·根据ID查询单个任务 ----》GET/todos/:id
·添加任务 ----》POST.todos
·修改任务 ---》PATCH/todos/:id
·删除任务 ---》DELETE/todos/:id

动态参数可以通过模板字符的写法,从请求参数中获取

app.get('/todos', (req, res) => {
    res.send('get/todos');
});
// 动态路由的使用
app.get('/todos/:id', (req, res) => {
    res.send(`get/todos/${req.params.id}`);
});
app.post('/todos', (req, res) => {
    res.send(`post/todos`);
});
app.patch('/todos/:id', (req, res) => {
    res.send(`patch/todos`);
});
app.delete('/todos', (req, res) => {
    res.send(`delete/todos/${req.params.id}`);
});

express不限制数据的存储位置,模拟的时候咱们放在json文件中吧~

// 1.引入fs模块
const fs = require("fs");
const app = express();
// 2. 尽量使用异步读取json文件的数据,
// 异步:readFile('json文件路径','utf8',回调函数接口两个参数,一个err,一个data)
// 同步:readFileSync如果使用同步的话,则不接受回调函数作为参数,且会阻塞执行线程直到文件读取完成
//--------------接口1获取任务列表---------
// 同步写法如下:
app.get("/todos", (req, res) => {
  try {
    const data = fs.readFileSync("./db.json", "utf8");
    const db = JSON.parse(data);
    res.status(200).json(db.todos);
  } catch (err) {
    // 如果发生错误,返回500状态码并发送错误信息
    res.status(500).json({ error: err.message });
  }
});
// 异步写法如下:
app.get("/todos", (req, res) => {
  const data = fs.readFile("./db.json", "utf8", (err, data) => {
    if (err) {
      // 如果发生错误,返回500状态码并发送错误信息
      return res.status(500).json({ error: err.message });
    }
    const db = JSON.parse(data);
    res.status(200).json(db.todos);
  });
});

//--------------接口2根据参数传递的ID获取对应的列表的数据项---------
app.get("/todos/:id", (req, res) => {
  //   res.send(`get/todos/${req.params.id}`);
  fs.readFile("./db.json", "utf8", (err, data) => {
    if (err) {
      return res.status(500).send({
        error: err.message,
      });
    }
    const db  = JSON.parse(data);
    const todo = db.todos.find(todo=>todo.id===Number.parseInt(req.params.id))
   if (!todo) {
      return res.status(404).send("找不到该条数据项");
    }
    res.status(200).send(todo)
  });
});

插曲:
每次都要写fs.readFile ,json.parse太麻烦了,封装一下
将callback形式异步APi,通过node.js中的util工具中的promisify转换成promise的形式

  1. 根目录下创建db.js,进行代码封装
const fs = require("fs");
const { promisify } = require("util");
const path = require("path");
const readFile = promisify(fs.readFile);
const dbPath = path.join(__dirname, "./db.json");

exports.getDB = async () => {
  const data = await readFile(dbPath, "utf8");
  return JSON.parse(data);
};

  1. 在app.js中引入使用,且修改
const express = require("express");
// 1.引入fs模块
const fs = require("fs");
//2. 引入db.js中封装好的方法
const { getDB } = require("./db");
const app = express();
app.get("/todos", async (req, res) => {
  try {
    const db = await getDB();
    res.status(200).json(db.todos);
  } catch (err) {
    return res.status(500).json({ error: err.message });
  }
});
// 动态路由的使用
app.get("/todos/:id", async (req, res) => {
  try {
    const db = await getDB();
    const todo = db.todos.find((todo) => todo.id === Number.parseInt(req.params.id));
    if (!todo) {
      return res.status(404).send("找不到该条数据项");
    }
    res.status(200).send(todo);
  } catch (err) {
    return res.status(500).json({ error: err.message });
  }
});

//--------------接口3 写入列表新数据项---------
第三个接口,post请求体,1)获取客户端请求体参数 2)数据验证 3)验证通过则把数据储存到DB中 4)发送响应,告知成功

1)获取客户端请求体参数
a) application/json格式:
在app实例中挂载一下express.json()来配置解析表单请求体,然后通过request.body获取用户传递的请求体参数;

app.use(express.json())

b) application/x-www-form-urlencoded格式:

app.use(express.urlencoded())

2)获取客户端请求体参数 与 数据验证

// 1.引入express
const express = require("express");
//2. 引入db.js中封装好的方法
const { getDB, saveDB } = require("./db");
const app = express();
app.use(express.json());
app.use(express.urlencoded());

// 写入数据 req.body获取请求体数据, 配置先
app.post("/todos", async (req, res) => {
  try {
    const db = await getDB();
    const reqBd = req.body;
    console.log(req.body, "请求体");
    // 如果传递的对象中不包含title,则提示用户输入不符合的参数了
    if (!reqBd.title) {
      return res.status(422).send({ error: "The field title is required" });
    }
    const lastTodoItem = db.todos[db.todos.length - 1];
    db.todos.push({
      id: lastTodoItem ? lastTodoItem.id + 1 : 1,
      title: reqBd.title
    });
    await saveDB(db)
    res.status(200).send("添加成功!");
  } catch (err) {
    res.status(500).send({ error: err.message });
  }
});

3)存储封装

const fs = require("fs");
const { promisify } = require("util");
const path = require("path");
const readFile = promisify(fs.readFile);
const dbPath = path.join(__dirname, "./db.json");
const writeFile = promisify(fs.writeFile) //引入写入模块方法
// 读取封装
exports.getDB = async () => {
  const data = await readFile(dbPath, "utf8");
  return JSON.parse(data);
};
// 写入封装
exports.saveDB = async (db) => {
    const data = JSON.stringify(db)
    // 如果需要Json文件渲染有格式化则传递第三个参数,表示格式的空格
    // const data = JSON.stringify(db,null,'  ')
    await writeFile(dbPath,data)
};


//--------------接口4 编辑列表数据项---------

app.patch("/todos/:id", async (req, res) => {
  // 1.获取用户传入的数据
  // 2.找到与之匹配的数据项
  // 3.进行替换且告知客户端
  try {
    const reqBd = req.body;
    const db = await getDB();
    const todoItem = db.todos.find(
      (todo) => todo.id === Number.parseInt(req.params.id)
    );
    if (!todoItem) {
      return res.status(422).send("没查询到对应的数据项,无法进行修改~");
    }
    // Object.assign(要被修改的数据项,传入的数据项且与被修改匹配的数据项) 如果有找到就替换,没找到就新增一条,但我们的逻辑中不允许新增,直接return报错提示,如上
    Object.assign(todoItem, reqBd);
    await saveDB(db);
    res.status(200).send("修改成功!");
  } catch (err) {
    res.status(500).send({ error: err.message});
  }
});

//--------------接口5 删除列表数据项---------

app.delete("/todos/:id", async (req, res) => {
  //   res.send(`delete/todos/${req.params.id}`);
  try {
    const db = await getDB();
    const todoItemIndex = db.todos.findIndex(
      (todo) => todo.id === Number.parseInt(req.params.id)
    );
    if (todoItemIndex===-1) {
      res.status(422).send("没有您要删除的数据项");
    }
    //根据下标删除 
    db.todos.splice(todoItemIndex,1);
    await saveDB(db);
    res.status(200).send('删除成功')
  } catch (err) {
    res.status(500).send({ error: err.message });
  }
});


标签:req,const,demo,express,改查,send,db,res,todos
From: https://www.cnblogs.com/jocelyn11/p/18458278

相关文章

  • 界面控件DevExpress WinForms v24.1新版亮点 - 可访问性和UI自动化增强
    DevExpressWinForms拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!DevExpressWinForms控件v24.1日前已经全新发布,新......
  • CANoe_调用C#控件的方法_DEMO方法演示
    1、DEMO存放位置D:\Users\Public\Documents\Vector\CANoe\SampleConfigurations11.0.96\CAN\MoreExamples\ActiveX_DotNET_Panels每个人的电脑因为有区别存放位置不一样2、控件制作--使用C#控件可以直接制作 3、控件代码usingSystem;usingSystem.Collections;usin......
  • express 的使用笔记1
    官网地址:http://expressjs.com/zh-cn/starter/installing.html1.安装与启动1)首先要有node环境,作为一个前端开发,肯定已经有啦,那就直接开一个项目demo,然后安装express,如下图:2)上面操作之后,项目文件里应该会有一个app.js入口文件,如果没有,则可以借用gitbash使用touchapp.js来创......
  • 使用DeepKE训练命名实体识别模型DEMO(官方DEMO)
    使用DeepKE训练命名实体识别模型DEMO(官方DEMO)说明:首次发表日期:2024-10-10DeepKE资源:文档:https://www.zjukg.org/DeepKE/网站:http://deepke.zjukg.cn/cnschema:http://cnschema.openkg.cn/如果需要,设置Github镜像gitconfig--systemurl."https://githubfast.com/"......
  • DevExpress WPF中文教程:如何解决数据更新的常见问题?
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。无论是Office办公软件的衍伸产品,还是以数据为......
  • Microsoft Expression Studio 4 MSDN中文旗舰版
    MicrosoftExpressionStudio4MSDN中文旗舰版复制   slice UID79171帖子5494PB币19816贡献0技术64活跃1938   楼主 发表于2010-10-1021:42:52 IP属地重庆本帖最后由slice于2010-10-1021:47编辑cn_expression_st......
  • DevExpress WPF中文教程:如何解决数据更新的常见问题?
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。无论是Office办公软件的衍伸产品,还是以数据为中心......
  • 【C#】DevExpress实现复合表头
    https://download.csdn.net/blog/column/9993043/120721622①将创建的GridControl下的GirdView1转化为BandGridView类型;②创建需要展示的列(指定列的名称【Name】、描述【caption】、数据字段名称【FieldName】)③绑定列实现复合表头。注意:如果复合表头有多行,则需要设置新增Band......
  • ERC20智能合约demo
    ERC20智能合约demoERC20.solIERC20.solERC20.sol//SPDX-License-Identifier:MITpragmasolidity^0.8.20;import{IERC20}from"./IERC20.sol";contractERC20isIERC20{mapping(address=>uint256)publicoverridebalanceOf; mapping(address......
  • C# SqlSugar增删改查
     staticvoidMain(string[]args){ConnectionConfigconnectionConfig=newConnectionConfig(){DbType=DbType.SqlServer,ConnectionString="Server=.;InitialCatalog=Test;User......