背景,我是一个很懒的人。学习新东西的动力,从来都不是xxx出了个新功能/版本,我要尝尝鲜之类的。每次都是有某些东西的实际需求,才会主动尝试去学习一些新东西,比如这次,后端资源缺乏,学学后端接口,自食其力。
框架
上次对接小爱同学,开发了一个基于node、express、mysql、axios的后端服务。这次不想那么麻烦,就直接在老框架上边进行二次开发。不过也算是正式了解了下express开发接口的流程
1、目录
目前目录结构,只是没想到,一个目录结构也能困扰挺久的。因为没写过正式的express项目,总是担心目录结构不够规范,老生常谈的MVC架构,到底是不是这样分,要不要把sql单独拎出来。来来回回删了好几次,最后一想,算了。一把梭就完事了。自己的项目怎么爽怎么来。内部系统,加上维护的人只有我自己。不用考虑代码目录的可读性。
2、中间件
小爱部分的接口是没有做权限校验的。但是api这边,后边会加上权限校验部分。翻了下express的路由发现use函数中,是有中间件函数的。
// app.js
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const port = 3000
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
let xiaoai = require('./router/xiaoai/index')
// 权限校验部分
let permission = require('./router/permission')
let purchaseManage = require('./router/purchaseManage/index')
// 小爱模块
app.use('/node', xiaoai);
// api部分
app.use('/nodeApi',permission, purchaseManage);
// 404
app.use(function(req, res, next) {
if(req.accepts('html') && res.status(404)) {
res.send('404: File Not Found');
}
});
const server = app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
// permission.js
const permission = (req,res,next) => {
console.log("校验函数")
// 权限校验 目前java那边暂未开发权限校验 所以直接next
// if(islogin){
next()
// }else{
// res.json({
// code: 401
// })
// }
}
module.exports = permission
3、sql封装
关于sql的封装,之前看到github上有传入json,自动转换为sql的。但是后来觉得自己来练练吧。就没有用上npm包。 整体思路是将sql执行封装为一个基础执行方法。和一些扩展方法,目前暂时还没有分页查询,正在解决分页查询中(碰到了数据总量问题,和分页参数返回问题)
// mysql 配置页面
const mysql = require("mysql");
const { defaultPageSize } = require('../config');
const { table } = require("../utils/log");
const logger = require('../utils/log')
const pool = mysql.createPool({
host: "xxx.xxx.xxx.xxx",
user: "xxx",
password: "xxx",
database: "xxx",
connectionLimit: 10
});
// sql 执行命令
const query = async (sql) => {
// 建立连接
// 查询
return new Promise((resolve, reject) => {
console.log('查询sql: ', sql)
pool.getConnection((err, conn) => {
if (err) {
logger.setLog(`============${new Date().toLocaleString()}和mysql数据库建立连接失败:${JSON.stringify(err)}=============`)
} else {
conn.query(sql, (err, rows,) => {
if (err) reject(err)
resolve(rows)
})
conn.release();
}
});
})
}
/**
* @description: 基础列表查询 分页
* @param {String} tableName 表名称
* @param {Object} pageObj 分页参数 { pageSize: 10 , pageNo: 1 }
* @param {Object} params 入参
* @return {Array} 查询结果列表
*/
const sqlQueryPageList = async (tableName, pageObj = { pageSize: defaultPageSize , pageNo: 1 }, params) => {
return new Promise((reslove, reject) => {
if(!tableName) reject("请输入表名");
const { pageSize, pageNo } = pageObj;
let whereStr = ''
// 拼接where参数
if(params && Object.keys(params)){
whereStr += 'where '
Object.keys(params).forEach((item,index) => {
whereStr += index ? `&& ${item}='${params[item]}'` : `${item}='${params[item]}'`
})
}
const sql = `select * from ${tableName} ${whereStr} limit ${(pageNo-1) * pageSize},${pageSize};`
query(sql).then(res => reslove(res)).catch(err => reject(err))
})
}
/**
* @description: 基础添加
* @param {String} tableName 表名称
* @param {Object} params 入参
* @return {*}
*/
const sqlAdd = async (tableName, params) => {
return new Promise((reslove, reject) => {
if(!tableName) reject("请输入表名");
let cloumnsArr = []
let values = []
// 拼接sql 参数
if(params && Object.keys(params)){
Object.keys(params).forEach((item,index) => {
cloumnsArr.push(item)
values.push(`"${params[item]}"`)
})
}
const sql = `insert into ${tableName} (${cloumnsArr.toString()}) values (${values.toString()})`
query(sql).then(res => reslove(res)).catch(err => reject(err))
})
}
/**
* @description: 基础修改
* @param {String} tableName 表名称
* @param {Object} condition 查询条件
* @param {Object} params 入参
* @return {*}
*/
const sqlUpdate = async (tableName,condition, params) => {
return new Promise((reslove, reject) => {
if(!tableName) reject("请输入表名");
let whereStr = ''
let paramsStr = ''
// 拼接where参数
if(params && Object.keys(params)){
Object.keys(params).forEach((item,index) => {
paramsStr += index ? `, ${item}='${params[item]}'` : `${item}='${params[item]}'`
})
}
if(condition && Object.keys(condition)){
Object.keys(condition).forEach((item,index) => {
whereStr += index ? `&& ${item}='${condition[item]}'` : `${item}='${condition[item]}'`
})
}
const sql = `UPDATE ${tableName} SET ${paramsStr} where ${whereStr} `
query(sql).then(res => reslove(res)).catch(err => reject(err))
})
}
/**
* @description: 基础删除
* @param {String} tableName 表名称
* @param {Object} params 入参
* @return {*}
*/
const sqlDelete = async (tableName, params) => {
return new Promise((reslove, reject) => {
if(!tableName) reject("请输入表名");
const { pageSize, pageNo } = pageObj;
let whereStr = ''
// 拼接where参数
if(params && Object.keys(params)){
whereStr += 'where '
Object.keys(params).forEach((item,index) => {
whereStr += index ? `&& ${item}='${params[item]}'` : `${item}='${params[item]}'`
})
}
const sql = `delete from ${tableName} where ${whereStr} `
query(sql).then(res => reslove(res)).catch(err => reject(err))
})
}
module.exports = {
query,
sqlQueryPageList,
sqlAdd,
sqlUpdate,
sqlDelete
}
4、待补充
目前正在开发中,学一些东西总要有些收获。后边会在补充