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 相关文章推荐
多个iframe自动调整大小的问题
Sep 18 Javascript
JavaScript 打地鼠游戏代码说明
Oct 12 Javascript
jquery阻止冒泡事件使用模拟事件
Sep 06 Javascript
JavaScript的继承的封装介绍
Oct 15 Javascript
javascript制作网页图片上实现下雨效果
Feb 26 Javascript
jQuery检测输入的字符串包含的中英文的数量
Apr 17 Javascript
初步了解javascript面向对象
Nov 09 Javascript
AngularJS中过滤器的使用与自定义实例代码
Sep 17 Javascript
深入掌握 react的 setState的工作机制
Sep 27 Javascript
Vue 组件封装 并使用 NPM 发布的教程
Sep 30 Javascript
Node.js中package.json中库的版本号(~和^)
Apr 02 Javascript
微信小程序用户拒绝授权的处理方法详解
Sep 20 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
apache2.2.4+mysql5.0.77+php5.2.8安装精简
2009/04/29 PHP
浅析51个PHP处理字符串的函数
2013/08/02 PHP
简单谈谈PHP中的include、include_once、require以及require_once语句
2016/04/23 PHP
抛弃 PHP 代价太高
2016/04/26 PHP
在Thinkphp中使用ajax实现无刷新分页的方法
2016/10/25 PHP
flash javascript之间的通讯方法小结
2008/12/20 Javascript
javascript window对象属性整理
2009/10/24 Javascript
JQery jstree 大数据量问题解决方法
2010/03/09 Javascript
js简单的表格添加行和删除行操作示例
2014/03/31 Javascript
Javascript中的delete操作符详细介绍
2014/06/06 Javascript
jquery中post方法用法实例
2014/10/21 Javascript
javascript关于运动的各种问题经典总结
2015/04/27 Javascript
jquery中val()方法是从最后一个选项往前读取的
2015/09/06 Javascript
JavaScript 数组中最大最小值
2016/06/05 Javascript
KVM虚拟化技术之使用Qemu-kvm创建和管理虚拟机的方法
2016/10/05 Javascript
原生JS实现旋转轮播图+文字内容切换效果【附源码】
2018/09/29 Javascript
vue缓存的keepalive页面刷新数据的方法
2019/04/23 Javascript
vue安装遇到的5个报错及解决方法
2019/06/12 Javascript
微信小程序简单的canvas裁剪图片功能详解
2019/07/12 Javascript
小程序中this.setData的使用和注意事项
2019/08/28 Javascript
JavaScript如何判断input数据类型
2020/02/06 Javascript
python连接mysql并提交mysql事务示例
2014/03/05 Python
跟老齐学Python之有容乃大的list(4)
2014/09/28 Python
Python数据结构与算法之常见的分配排序法示例【桶排序与基数排序】
2017/12/15 Python
python 3.3 下载固定链接文件并保存的方法
2018/12/18 Python
Flask框架学习笔记之路由和反向路由详解【图文与实例】
2019/08/12 Python
Python PO设计模式的具体使用
2019/08/16 Python
python 爬取百度文库并下载(免费文章限定)
2020/12/04 Python
CSS3实现渐变背景兼容问题
2020/05/06 HTML / CSS
打架检讨书100字
2014/01/19 职场文书
经济贸易系求职信
2014/08/04 职场文书
学习十八大的心得体会
2014/09/12 职场文书
美术教师个人总结
2015/02/06 职场文书
入团介绍人意见范文
2015/06/04 职场文书
销售人员管理制度
2015/08/06 职场文书
CSS 实现多彩、智能的阴影效果
2021/05/12 HTML / CSS