最近写了一个小玩意儿 - 零编码搞定整站 api 接口

解释下标题:玩意,本可以指某种有趣味的物件,但在汉语言的发展和民俗口语的发展过程中有了贬义的指代。所以这里是有趣的意思。

本文介绍一种方法,可以让你做一些小型项目时可以做到零代码生成接口。

先说问题

如果我们自己要开发一个完整的项目,也就是前后台都需要自己写,这里当然少不了需要写很多接口,这样的项目就像是你接了一个私活,钱少事儿多,因为前后台都要自己搞,工作量不小。

这种项目的架构就是个简单的三层架构,视图层、逻辑层、数据层。

数据层就是直接查库,通过sql语句查询数据,供逻辑层来使用,逻辑层对外提供一些数据访问接口,同时处理视图层的数据请求。

正常开发的话,你需要什么接口就硬编码来写,写方法名,对参数进行处理,然后写sql语句查询数据,还要维护一堆文件。

就好比下面这样:

其中一个文件的代码:

数据层的品牌管理

/**
 *  品牌类型管理
 */

import dbConnection from './db-connection';
const TB_NAME = 'tbClass';

export default {
    getAllBrands(classType) {
        const sql = `SELECT id,className,cusId,classType,addTime,pic,des from ${TB_NAME} WHERE classType=${classType} order BY ID Desc;`;
        return dbConnection.query(sql);
    },
    getBrandDetails(id) {
        const sql = `SELECT id,className,cusId,classType,pic,des from ${TB_NAME} WHERE id=${id};`;
        return dbConnection.query(sql);
    },
    getCurBrand(className){
        const sql = `SELECT id,className,cusId,classType,pic,des from ${TB_NAME} WHERE className='${className}';`;
        return dbConnection.query(sql); 
    },
    addBrand(opt){
        const sql = `INSERT INTO ${TB_NAME}(className,cusId,classType,pic,des)
                VALUES('${opt.className}','${opt.cusId}','${opt.classType}','${opt.pic}','${opt.des}')
                `;
        return dbConnection.query(sql);        
    },
    updateBrand(opt) {
        opt.id = parseInt(opt.id, 10);
        const sql = `UPDATE ${TB_NAME} SET className='${opt.className}',pic='${opt.pic}',des='${opt.des}' WHERE ID=${opt.id};`;
        return dbConnection.query(sql);
    },
    deleteBrand(opt) {
        opt.id = parseInt(opt.id, 10);
        const sql = `DELETE FROM ${TB_NAME} WHERE ID=${opt.id};`;
        return dbConnection.query(sql);
    }
}

对应的逻辑层 品牌管理

//api/brands
import dbBrands from '../db-common/brands';

export default {
    //获得品牌列表
    getBrandList: async () => {
        const data = await dbBrands.getAllBrands(1000);
        return data;
    },
    //获得类型列表
    getTypeList: async () => {
        const data = await dbBrands.getAllBrands(2000);
        return data;
    },
    getAllBrands: async (opt)=>{ 
        const data = await dbBrands.getAllBrands(opt.classType);
        return data;
    },
    getBrandDetails: async (opt) => {
        if(!opt.id){
            return false;
        }
        return dbBrands.getBrandDetails(opt.id)
    },
    moidfyBrand: async (opt) => {
        if (!opt.id || !opt.className) {
            return false;
        }
        const res = await dbBrands.updateBrand(opt);
        if (res.affectedRows > 0) {
            return true;
        }
        return false;
    },
    addBrand: async (opt) => {
        if (!opt.classType || !opt.className) {
            return false;
        }
        const curBrand = await dbBrands.getCurBrand(opt.className);
        if(curBrand.length > 0){
            return {
                'error_code': 100,
                'error_msg': '名称已存在'
            };
        }else{
            const res = await dbBrands.addBrand(opt);
            if (res.affectedRows > 0) {
                return true;
            }
        }
        return false;
    },
    deleteBrand: async (opt) => {
        if (!opt.id) {
            return false;
        }
        const res = await dbBrands.deleteBrand(opt);
        if (res.affectedRows > 0) {
            return true;
        }
        return false;
    }
}

发现问题

看了上面代码有没有发现什么问题?

逻辑很少,倒是重复的代码很多,新增一个接口需要搞很多自己都感觉没意义的代码,时间成本高,唯一的好处就是可读性高,结构清晰。

所以我不想再写这样的代码了,不对,是粘贴复制,真的没意义,还费键盘。

解决问题

如何解决?

其实很简单,通过一个配置文件轻松搞定。

把接口相关的信息,以及所需要的参数和数据源通通写入配置文件。

然后写一个中间件来处理该配置文件即可。

说的再多不如上代码,看配置文件

export default {
  "/feapi/products/getAllList": {//接口地址
    "method": "get|post",//请求类型 
    "des": "查询xxxx列表",//接口名称
    "paramType":"pager",
    "reqOptParams":{//参数配置,接口需要的参数写在这里,
      sycx:{
        isRequire:false, //是否必填
        type:'string'//参数类型
      },
      addWhere:{
        isRequire:false,
         type:'string'//参数类型
      }
    },
    "response": { //数据源配置,可以是从数据查询,也可以从文件,也可以是一个json对象
      "source": "db",
      "sql": "select a.id,a.sycx,a.newModel,a.oldModel,a.innerJ,a.outerJ,a.heHeight,a.addWhere,a.yearCount from tbCarModel a ",
      "json": "{\"isok\":\"fdfdfdf\"}",
      "file_json": "file_json/aaa.json"
    }
  }
}

上面就是全部的配置内容,具体字段的意思也有注释,后面需要接口就增加一个配置就完事儿。分分钟,省时省力。

当然上面是一个基础配置,能满足的场景可能有限(更多场景也能满足,想办法放到配置里就行),对于增删改查,分页查询,动态条件查询都没啥问题,我已经实现了,也用在了具体项目中。源码就不贴了,没啥难度,有需要可以私信我。

看到这里,有什么想说的吗?

我觉得价值巨大,因为能省时间,时间就是生命。

虽然路子很野,但很有效。现在增加一个接口,就是分分钟。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zz_jesse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值