koa2 數(shù)據(jù)api中間件設(shè)計(jì)模型的實(shí)現(xiàn)方法
假設(shè)所有的數(shù)據(jù)庫(kù)讀取,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ā)的中間件包裝起來(lái)
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);
依賴(lài)關(guān)系
看著貌似解決了,但如何處理具有上下文依賴(lài)的情況呢?例如 api_1 依賴(lài) 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);
跳過(guò)中間件
有時(shí)候,需要根據(jù)特定的條件,繞過(guò)某些接口調(diào)用
改造下 api.js,通過(guò)加入過(guò)濾列表
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 將所有需要的中間件組合起來(lái),在寫(xiě)一個(gè)針對(duì)頁(yè)面的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)大量的接口、邏輯操作,超長(zhǎng)的上下文邏輯。
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 模擬滑動(dòng)拼圖驗(yàn)證碼操作的示例代碼
本篇文章主要介紹了使用 Node.js 模擬滑動(dòng)驗(yàn)證碼操作的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
Node.js處理I/O數(shù)據(jù)之使用Buffer模塊緩沖數(shù)據(jù)
這篇文章介紹了Node.js使用Buffer模塊緩沖數(shù)據(jù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
Node.js使用bcrypt-pbkdf實(shí)現(xiàn)密碼加密
在這個(gè)數(shù)字時(shí)代,保護(hù)用戶(hù)密碼的重要性不言而喻,作為一名資深的前端開(kāi)發(fā)工程師和技術(shù)博客作者,今天我將帶你詳細(xì)了解如何在 Node.js 環(huán)境中利用 bcrypt-pbkdf 模塊進(jìn)行密碼的哈希處理,確保你的應(yīng)用安全性得到有效提升,需要的朋友可以參考下2024-05-05
node使用mysql獲取數(shù)據(jù)庫(kù)數(shù)據(jù)中文亂碼問(wèn)題的解決
這篇文章主要介紹了node使用mysql獲取數(shù)據(jù)庫(kù)數(shù)據(jù)中文亂碼問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
nodeJS與MySQL實(shí)現(xiàn)分頁(yè)數(shù)據(jù)以及倒序數(shù)據(jù)
這篇文章主要介紹了nodeJS與MySQL實(shí)現(xiàn)分頁(yè)數(shù)據(jù)以及倒序數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06

