koa2 数据api中间件设计模型的实现方法


Posted in Javascript onJuly 13, 2020

假设所有的数据库读取,http api 接口请求都为一个中间件,将中间件当做插件,插入需要获取数据的位置。

api.js

module.exports = async (ctx, next) => {
 ctx.share_data.api_data = await axios.get('/api');

 await next();
};

db.js

module.exports = async (ctx, next) => {
 ctx.share_data.db_data = await mysql_query('SELECT XXX').catch(() => {});

 await next();
};

串联

app.js

const api = require('api.js');
const db = require('db.js');
          
app.get('/get-api', api, (ctx) => ctx.body = ctx.share_data);
app.get('/get-db', db, (ctx) => ctx.body = ctx.share_data);
app.get('/get-api-and-db', api, db, (ctx) => ctx.body = ctx.share_data);

看着挺和谐,但是如果有多个数据中间件串联则会导致接口的响应时间为所有中间件的总和。

并发

可义一个 compose 函数,需要并发的中间件包装起来

super-compose.js

module.exports = (middleware = []) => {
 if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!');
 for (const fn of middleware) {
  if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!');
 }

 return async (context = {}, next = f => f) => {
  await Promise.all(
   middleware.map(middleware => {
    return new Promise((rs, rj) => {
     middleware(context, () => Promise.resolve())
      .then(rs)
      .catch(rj);
    });
   }),
  );

  await next();
 };
};

app.js

const api = require('api.js');
const db = require('db.js');
const superCompose = require('super-compose.js');
          
app.get('/get-api-and-db', superCompose([api, db]), (ctx) => ctx.body = ctx.share_data);

依赖关系

看着貌似解决了,但如何处理具有上下文依赖的情况呢?例如 api_1 依赖 api 的数据。
改下 api.js,加上缓存校验。处理可能被多次compose的重复接口调用

module.exports = async (ctx, next) => {
 if (ctx.share_data.api_data) {
  return await next();
 }

 ctx.share_data.api_data = await axios.get('/api');

 await next();
};

api-1.js

const api = require('api.js');

module.exports = compose([
 api,
 async (ctx, next) => {
  const { api_data: { api_data: { id = 0 } = {} } = {} } = ctx;

  if (id < 0) {
   await next();
  } else {
   ctx.api_data.api_1_data = await axios.get('/api', { params: { id } });
  }

  await next();
 },
])

app.js

const api_1 = require('api_1.js');
const db = require('db.js');
const superCompose = require('super-compose.js');
          
app.get('/get-api-and-db', superCompose([api_1, db]), (ctx) => ctx.body = ctx.share_data);

跳过中间件

有时候,需要根据特定的条件,绕过某些接口调用

改造下 api.js,通过加入过滤列表

module.exports = async (ctx, next) => {
 const { break_list = [] } = ctx;


 if (break_list.includes('api_data')) {
  // 可能会误伤其他组合引用该中间件的情况。
  // 如可能会误伤,可加上。
  // ctx.break_list = break_list.filter(v => v !== 'api_data')
  return await next();
 } else {
  ctx.share_data.api_data = await axios.get('/api');
 }

 await next();
}

app.js

const api = require('api.js');
const db = require('db.js');
const superCompose = require('super-compose.js');
          
app.get(
 '/get-api-and-db',
 async (ctx, next) => {
  ctx.break_list = ['api_data'];
  await next();
 },
 superCompose([api, db]),
 ctx => (ctx.body = ctx.share_data)
);

数据合并处理

结合 super-compose 与 koa-compose 将所有需要的中间件组合起来,在写一个针对页面的controller

const api = require('api.js');
const db = require('db.js');
const superCompose = require('super-compose.js');
const compost = rquire('koa-compose')

const babala = compose([
 superCompose([api, db]),
 async (ctx, next) => {
  const {
   share_data: { api_data: { id = 0 } = {}, db_data: { title } = {} } = {},
  } = ctx;

  ctx.body = { id, title };
  // OR
  // ctx.share_data.babala = {}
 },
]);

app.get(
 '/get-api-and-db',
 babala
);

结尾

解决经常出现的一个函数内大量的接口、逻辑操作,超长的上下文逻辑。

app.get('/api', async ctx => {
 const api_1 = await axios.get('/api_1');
 await api_2 = await axios.get('/api_2');

 // ...
 // ...
 // 这里有一百行
 // ... 
 
 const [api_3, api_4] = await new Promise.all([axios.get('/api_3'), axios.get('/api_4')]);
 
 // ...
 // ...
 // 这里有几百行
 // ...

 ctx.body = {};
});

以上就是koa2 数据api中间件设计模型的实现方法的详细内容,更多关于koa2 中间件设计模型的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
event.srcElement 用法笔记e.target
Dec 18 Javascript
Jquery ajax传递复杂参数给WebService的实现代码
Aug 08 Javascript
通过javascript获取iframe里的值示例代码
Jun 24 Javascript
JS脚本defer的作用示例介绍
Jan 02 Javascript
node.js下when.js 的异步编程实践
Dec 03 Javascript
手机开发必备技巧:javascript及CSS功能代码分享
May 25 Javascript
JavaScript实现九九乘法表的简单实例
Jun 07 Javascript
Bootstrap使用基础教程详解
Sep 05 Javascript
用纯Node.JS弹出Windows系统消息提示框实例(MessageBox)
May 17 Javascript
关于vuejs中v-if和v-show的区别及v-show不起作用问题
Mar 26 Javascript
Vue实现PC端靠边悬浮球的代码
May 09 Javascript
three.js着色器材质的内置变量示例详解
Aug 16 Javascript
浅析JavaScript 函数防抖和节流
Jul 13 #Javascript
详解JavaScript 异步编程
Jul 13 #Javascript
javascript canvas时钟模拟器
Jul 13 #Javascript
微信小程序整个页面的自动适应布局的实现
Jul 12 #Javascript
uniapp 仿微信的右边下拉选择弹出框的实现代码
Jul 12 #Javascript
微信小程序实现列表滚动头部吸顶的示例代码
Jul 12 #Javascript
Js on及addEventListener原理用法区别解析
Jul 11 #Javascript
You might like
优化php效率,提高php性能的一些方法
2011/03/24 PHP
巧用php中的array_filter()函数去掉多维空值的代码分享
2012/09/07 PHP
php实现curl模拟ftp上传的方法
2015/07/29 PHP
PHP-FPM之Chroot执行环境详解
2015/08/03 PHP
简单的前端js+ajax 购物车框架(入门篇)
2011/10/29 Javascript
浮动的div自适应居中显示的js代码
2013/12/23 Javascript
javascript实现带节日和农历的日历特效
2015/02/01 Javascript
jQuery实现延迟跳转的方法
2015/06/05 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之主动触发事件和模拟冒泡处理
2015/11/24 Javascript
用NODE.JS中的流编写工具是要注意的事项
2016/03/01 Javascript
jQuery实现多张图片上传预览(不经过后端处理)
2017/04/29 jQuery
jquery DataTable实现前后台动态分页
2017/06/17 jQuery
Node.js学习之地址解析模块URL的使用详解
2017/09/28 Javascript
为什么说JavaScript预解释是一种毫无节操的机制详析
2018/11/18 Javascript
微信小程序实现swiper切换卡内嵌滚动条不显示的方法示例
2018/12/20 Javascript
vue-cli webpack配置文件分析
2019/05/20 Javascript
vue+element模态框中新增模态框和删除功能
2019/06/11 Javascript
微信小程序 轮播图实现原理及优化详解
2019/09/29 Javascript
vue页面引入three.js实现3d动画场景操作
2020/08/10 Javascript
[40:27]完美世界DOTA2联赛PWL S3 PXG vs GXR 第一场 12.19
2020/12/24 DOTA
[01:15:16]DOTA2-DPC中国联赛 正赛 Elephant vs Aster BO3 第一场 1月26日
2021/03/11 DOTA
python刷投票的脚本实现代码
2014/11/08 Python
使用grappelli为django admin后台添加模板
2014/11/18 Python
python实现控制台打印的方法
2019/01/12 Python
解决pycharm工程启动卡住没反应的问题
2019/01/19 Python
python钉钉机器人运维脚本监控实例
2019/02/20 Python
pandas实现将日期转换成timestamp
2019/12/07 Python
python开发实例之python使用Websocket库开发简单聊天工具实例详解(python+Websocket+JS)
2020/03/18 Python
HTML5头部标签的一些常用信息小结
2016/10/23 HTML / CSS
考试作弊被抓检讨书
2014/01/10 职场文书
银行简历自我评价
2014/02/11 职场文书
关于祖国的演讲稿
2014/05/04 职场文书
2014年学校卫生工作总结
2014/11/20 职场文书
街道党风廉政建设调研报告
2015/01/01 职场文书
社区服务活动报告
2015/02/05 职场文书
2016年国庆节新闻稿范文
2015/11/25 职场文书