koa2 數(shù)據(jù)api中間件設(shè)計(jì)模型的實(shí)現(xiàn)方法
假設(shè)所有的數(shù)據(jù)庫讀取,http api 接口請(qǐng)求都為一個(gè)中間件,將中間件當(dāng)做插件,插入需要獲取數(shù)據(jù)的位置。
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();
};
串聯(lián)
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);
看著挺和諧,但是如果有多個(gè)數(shù)據(jù)中間件串聯(lián)則會(huì)導(dǎo)致接口的響應(yīng)時(shí)間為所有中間件的總和。
并發(fā)
可義一個(gè) compose 函數(shù),需要并發(fā)的中間件包裝起來
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);
依賴關(guān)系
看著貌似解決了,但如何處理具有上下文依賴的情況呢?例如 api_1 依賴 api 的數(shù)據(jù)。
改下 api.js,加上緩存校驗(yàn)。處理可能被多次compose的重復(fù)接口調(diào)用
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);
跳過中間件
有時(shí)候,需要根據(jù)特定的條件,繞過某些接口調(diào)用
改造下 api.js,通過加入過濾列表
module.exports = async (ctx, next) => {
const { break_list = [] } = ctx;
if (break_list.includes('api_data')) {
// 可能會(huì)誤傷其他組合引用該中間件的情況。
// 如可能會(huì)誤傷,可加上。
// 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)
);
數(shù)據(jù)合并處理
結(jié)合 super-compose 與 koa-compose 將所有需要的中間件組合起來,在寫一個(gè)針對(duì)頁面的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
);
結(jié)尾
解決經(jīng)常出現(xiàn)的一個(gè)函數(shù)內(nèi)大量的接口、邏輯操作,超長的上下文邏輯。
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 數(shù)據(jù)api中間件設(shè)計(jì)模型的實(shí)現(xiàn)方法的詳細(xì)內(nèi)容,更多關(guān)于koa2 中間件設(shè)計(jì)模型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用Node.js實(shí)現(xiàn)HTTP 206內(nèi)容分片的教程
這篇文章主要介紹了使用Node.js實(shí)現(xiàn)HTTP 206內(nèi)容分片的教程,Node.js是一款用于服務(wù)器端的JavaScript框架,需要的朋友可以參考下2015-06-06
利用Node.JS實(shí)現(xiàn)郵件發(fā)送功能
其實(shí)利用Node.JS實(shí)現(xiàn)郵件發(fā)送這個(gè)功能很多人都寫過了,但是網(wǎng)上有的代碼不能用,版本較老,所以想著寫下自己摸索的方法來實(shí)現(xiàn)?,F(xiàn)在分享給大家,感興趣的朋友們可以一起學(xué)習(xí)學(xué)習(xí)。2016-10-10
npm報(bào)錯(cuò):npm?WARN?config?global?'--global',?&apo
這篇文章主要給大家介紹了關(guān)于npm報(bào)錯(cuò):npm?WARN?config?global?'--global',?'--local'?are?deprecated.?Use?`--location=global`?instead.的解決方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
詳解如何實(shí)現(xiàn)一個(gè)簡單的Node.js腳手架
本篇文章主要介紹了如何實(shí)現(xiàn)一個(gè)簡單的Node.js腳手架,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12
推薦 21 款優(yōu)秀的高性能 Node.js 開發(fā)框架
Node.js是JavaScript中最為流行的框架之一,易于創(chuàng)建可擴(kuò)展的Web應(yīng)用。Node.js包含不同類型框架,包括MVC, full-stack,REST API以及Generators。借助這些框架使Node.js更加易于使用,它還支持眾多特性功能,只需幾個(gè)步驟就可快速搭建強(qiáng)大的Web應(yīng)用。本文為大家推薦21款2014-08-08
webstorm配置支持nodejs并自動(dòng)補(bǔ)全的方法
今天小編就為大家分享一篇webstorm配置支持nodejs并自動(dòng)補(bǔ)全的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-05-05
Grunt針對(duì)靜態(tài)文件的壓縮,版本控制打包的實(shí)例講解
下面小編就為大家?guī)硪黄狦runt針對(duì)靜態(tài)文件的壓縮,版本控制打包的實(shí)例講解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09

