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 相关文章推荐
jquery 操作日期、星期、元素的追加的实现代码
Feb 07 Javascript
js 为label标签和div标签赋值的方法
Aug 08 Javascript
JS、CSS加载中的小问题探讨
Nov 26 Javascript
jQuery 处理页面的事件详解
Jan 20 Javascript
基于Flowplayer打造一款免费的WEB视频播放器附源码
Sep 06 Javascript
JS中使用apply方法通过不同数量的参数调用函数的方法
May 31 Javascript
仅一个form表单 js实现注册信息依次填写提交功能
Jun 12 Javascript
对称加密与非对称加密优缺点详解
Feb 06 Javascript
vue 中filter的多种用法
Apr 26 Javascript
详解React之父子组件传递和其它一些要点
Jun 25 Javascript
jQuery实现网页拼图游戏
Apr 22 jQuery
js实现3D照片墙效果
Oct 28 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下获取http状态的实现代码
2014/05/09 PHP
Zend Framework连接Mysql数据库实例分析
2016/03/19 PHP
php fread读取文件注意事项
2016/09/24 PHP
PHP手机短信验证码实现流程详解
2018/05/17 PHP
[转]JS宝典学习笔记
2007/02/07 Javascript
IE8 兼容性问题(属性名区分大小写)
2009/06/04 Javascript
Json字符串转换为JS对象的高效方法实例
2013/05/01 Javascript
JavaScript获取伪元素(Pseudo-Element)属性的方法技巧
2015/03/13 Javascript
jquery+html5制作超酷的圆盘时钟表
2015/04/14 Javascript
JavaScript中数据结构与算法(三):链表
2015/06/19 Javascript
浅谈jquery中delegate()与live()
2015/06/22 Javascript
jQuery里filter()函数与find()函数用法分析
2015/06/24 Javascript
《JavaScript函数式编程》读后感
2015/08/07 Javascript
javascript html实现网页版日历代码
2016/03/08 Javascript
asp.net+jquery.form实现图片异步上传的方法(附jquery.form.js下载)
2016/05/05 Javascript
jQuery1.9+中删除了live以后的替代方法
2016/06/17 Javascript
js中window.open的参数及注意注意事项
2016/07/06 Javascript
AngularJs bootstrap搭载前台框架——准备工作
2016/09/01 Javascript
浅谈js的异步执行
2016/10/18 Javascript
require.js+vue开发微信上传图片组件
2016/10/27 Javascript
JQuery ZTree使用方法详解
2017/01/07 Javascript
JS动态添加元素及绑定事件造成程序重复执行解决
2017/12/07 Javascript
Vuex 单状态库与多模块状态库详解
2018/12/11 Javascript
深入koa-bodyparser原理解析
2019/01/16 Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
2019/03/19 Javascript
js实现盒子滚动动画效果
2020/08/09 Javascript
解决antd datepicker 获取时间默认少8个小时的问题
2020/10/29 Javascript
浅谈Python用QQ邮箱发送邮件时授权码的问题
2018/01/29 Python
django重新生成数据库中的某张表方法
2019/08/28 Python
iframe跨域的几种常用方法
2019/11/11 HTML / CSS
外国语学院毕业生自荐信
2013/10/28 职场文书
购房意向书
2014/04/01 职场文书
幼儿园老师寄语
2014/04/03 职场文书
道德之星事迹材料
2014/05/03 职场文书
三分钟自我介绍演讲稿
2014/08/21 职场文书
2014年大学教师工作总结
2014/12/02 职场文书