node开发之写接口开发总结

最新更新时间:2021年03月16日14:54:46
《猛戳-查看我的博客地图-总有你意想不到的惊喜》

本文内容:用egg-js开发接口

编写 CRUD (create, read, update, delete)语句
  • 查询数据库
//read 方案一:query+sql语句
let sql = `SELECT COUNT(*) from table1; SELECT * from table2`;
this.ctx.app.mysql.query(sql);//异步

//read 方案二:get
this.ctx.app.mysql.get('talbe1');//异步 查询一条

//read 方案三
this.ctx.app.mysql.get('talbe1',{name:'wanshaobo'});//异步 查询全表
let obj = {
	where:{name: 'wanshaobo'},
	orders: [['age','desc'],...],
	limit: 10,
	offser: 0,
}
this.ctx.app.mysql.select('talble1',obj);//异步 按照条件查询

多表查询的方案:JOIN LEFT表连接;CREATE VIEW创建视图;逐表查询(先查询到表1的id,再通过id查询表2的name,最后通过name字段查询表3的数据);

  • 获取和返回接口入参和出参
@post('/getList')
async getList(){
	this.ctx.request.body.name;//wanshaobo 读取前端传入接口的参数
	this.ctx.request.body.age;//30 读取前端传入接口的参数
}

@get('/getList')
async getList(){
	this.ctx.query.name;//wanshaobo 读取前端传入接口的参数
	this.ctx.query.age;//30 读取前端传入接口的参数
}
查表操作报错记录
SELECT * from table1 WHERE is_deleted = 0 order by set_time DESC;
  • 报错:nodejs.PROTOCOL_CONNECTION_LOSTError: Connection lost: The server closed the connection.

原因:table1表中没有set_time列

通过流的形式下载文件的接口
  • 文件放在了cdn上
// eggDemo/server/src/app/controller/download.ts
@get('/download')
async download() {
	const url = 'https://test.cdn.com/a.js';
	const res = await this.ctx.curl(url, {
		streaming: true,
	});
	this.ctx.type = 'js';
	this.ctx.body = res.res;
}
  • 文件放在了egg的静态资源服务上
// eggDemo/server/src/app/controller/download.ts
// app.config.static.dir -> eggDemo/server/src/app/public
const fs = require("fs");
const path = require("path");
@get('/download')
async download() {
    // @ts-ignore
    const ctx = this.ctx;
    const { app } = ctx;
    const filePath = path.resolve(app.config.static.dir,'a.js');
    this.ctx.attachment('a.js');
    this.ctx.set('Content-Type', 'application/octet-stream');
    this.ctx.body = fs.createReadStream(filePath);
}
Eggjs中获取http请求参数的基本方式
  • get
async getUser(){
    const { ctx } = this;
    const { id } = ctx.query
}
  • post
async getUser(){
    const { ctx } = this;
    const { id } = ctx.request.body;
}
  • put
router.put('/update/:id', controller.home.update);
async update(){
    const { ctx } = this;
    const { id } = ctx.params;
}
  • delete
router.delete('/del/:id', controller.home.del);
async delete(){
    const { ctx } = this;
    const { id } = ctx.params;
}
拼接sql语句的安全性校验
  • 静态查询语句,使用 query 可以执行合法的 sql 语句,无需做安全性校验
let sql = `SELECT * from table1 WHERE is_deleted = 0`;
let result = await this.ctx.app.mysql.query(sql);
  • 动态查询语句,需要对查询条件 condition 的 key和value 做安全性校验,防止sql注入
//如果key和value来自前端传入的数据,防止sql注入,需要做安全性检验
@post('/getList')
async getList(){
    const { app,request } = this.ctx;
	let k = request.body.key;
	let v = request.body.value;
	k = app.mysql.escapeId(k);
	v = app.mysql.escape(v);
	let condition = ` and ${k}=${v}`
	let sql = `SELECT * FROM table1 WHERE is_deleted = 0 ${condition}`;
	let result = await this.ctx.app.mysql.query(sql);
}
  • escapeId()和escape()

escapeId()对sql查询标识符进行编码,escape()对查询的值进行编码,参考这里这里这里

insert语句和update语句返回值中的insertId不一致
//如果key和value来自前端传入的数据,防止sql注入,需要做安全性检验
@post('/save')
async saveData(){
    const { app,request } = this.ctx;
    let insertRes = null;
    //新增一条数据
    insertRes = await app.mysql.insert('table1',{name:'wanshaobo'});//insertRes.insertId是table1表新增行的主键
    let updateRes = null;
    //修改已有数据
    updateRes = await app.mysql.update('table',{id: insertRes.insertId, name:'qinlike'});//updateRes.insertId 不是table1表中被更新的行的主键 而是上一次insert操作返回的id
}
参考资料

感谢阅读,欢迎评论^-^

打赏我吧^-^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值