Koa介紹
Koa 是下一代的 Node.js 的 Web 框架辟灰。由 Express 團(tuán)隊(duì)設(shè)計(jì)芥喇。旨在提供一個(gè)更小型凰萨、更富有表現(xiàn)力、更可靠的 Web 應(yīng)用和 API 的開發(fā)基礎(chǔ)胖眷。
Koa可以通過生成器擺脫回調(diào)珊搀,極大地改進(jìn)錯(cuò)誤處理。Koa核心不綁定任何中間件境析,但提供了優(yōu)雅的一組可以快速和愉悅地編寫服務(wù)器應(yīng)用的方法派诬。
安裝
Koa 依賴 node v7.6.0 或 ES2015及更高版本和 async 方法支持.
使用npm安裝
npm i koa
引入
導(dǎo)入koa包默赂,并創(chuàng)建app
/**
* 引入框架
*/
const Koa = require('koa');
// 創(chuàng)建app對(duì)象
const app = new Koa();
使用
- 第一個(gè)服務(wù)
// 監(jiān)聽請求并返回響應(yīng)缆八,這里響應(yīng)字符串 "hello , index"
app.use(async context => {
context.body = 'hello , index';
});
//啟動(dòng)服務(wù)疾捍,綁定端口
app.listen(3000, () => {
console.log('服務(wù)啟動(dòng)成功!');
});
use方法
use方法實(shí)際上執(zhí)行順序是從上往下執(zhí)行,但是當(dāng)使用await next(); 之后默認(rèn)會(huì)將use關(guān)聯(lián)的方法壓入棧中冯挎,先壓入得方法后執(zhí)行房官。類似于java中阻塞線程得等待续滋。
-
可以使用該特性制作N多中間層,進(jìn)行數(shù)據(jù)的處理及業(yè)務(wù)邏輯的封裝疲酌。
/**
* 攔截請求,打出log日志湿颅。
* 將該中間層放在棧的最頂層油航。順序await之前從上往下怀浆,阻塞之后從下往上走。
*/
app.use(async (context, next) => {
// 等待上層執(zhí)行完成
await next();
// 獲取本次響應(yīng)的時(shí)間
const responseTime = context.response.get('X-Response-Time');
// 打印
console.log(`${context.method} :: ${responseTime} - ${context.url}`);
});
/**
* 往請求響應(yīng)頭中寫入響應(yīng)時(shí)間
*/
app.use(async (context, next) => {
// 請求之前記錄當(dāng)前時(shí)間
const start = Date.now();
// 等待上層執(zhí)行完成
await next();
// 響應(yīng)之后計(jì)算等待時(shí)間單位毫秒
const ms = Date.now() - start;
context.set('X-Response-Time', `${ms}ms`);
});
路由模塊 koa-router
路由模塊使用koa-route,該模塊可以簡單高效的完成接口對(duì)象的抽取及綁定镰踏。
參考
-
使用npm安裝
npm install koa-router
-
引入koa-router
/**
* 引入第三方路由模塊
*/
const _ = require('koa-route');
var router = new _();
-
使用奠伪,路由集合方式
// 請求路由集合
const pets = {
'/about': context => {
context.response.type = 'html';
context.response.body = '<a href="/">關(guān)于頁面</a>';
},
'/login': context => {
context.response.type = 'html';
context.response.body = '<div>登錄頁面</div>';
},
'/reg': context => {
context.response.body = '注冊頁面';
},
'/mine': context => {
context.response.type = 'html';
context.response.body = '<div>個(gè)人中心</div>';
},
'/show/:name': (context, name) => {
context.response.type = 'html';
context.response.body = '<div>個(gè)人中心 ' + `${name}` + ' </div>';
}
};
// 添加路由
Object.keys(pets).forEach(function (key) {
app.use(_.get(key, pets[key]));
});
-
單個(gè)路由過濾
// 路由home路徑的get請求
router.get('/home', async (ctx, next) => {
ctx.body = 'we are at home!';
return next();
}, async (ctx, next) => {
ctx.body = 'home 2';
});
// 對(duì)應(yīng)HTTP對(duì)應(yīng)的動(dòng)作绊率,all代表所有的請求方式
router
.get('/', async (ctx, next) => {
ctx.body = 'Hello World!';
})
.post('/users', async (ctx, next) => {
})
.put('/users/:id', async (ctx, next) => {
})
.del('/users/:id', async (ctx, next) => {
})
.all('/users/:id', async (ctx, next) => {
});
// 將路徑路由添加到app
app
.use(router.routes())
.use(router.allowedMethods());
附上Demo代碼
/**
* 引入框架
*/
const Koa = require('koa');
// 創(chuàng)建app對(duì)象
const app = new Koa();
/**
* 引入第三方路由模塊
*/
const _ = require('koa-route');
var router = new _();
/**
* 攔截請求即舌,打出log日志顽聂。
* 將該中間層放在棧的最頂層盯仪。順序await之前從上往下,阻塞之后從下往上走全景。
*/
app.use(async (context, next) => {
// 等待上層執(zhí)行完成
await next();
// 獲取本次響應(yīng)的時(shí)間
const responseTime = context.response.get('X-Response-Time');
// 打印
console.log(`${context.method} :: ${responseTime} - ${context.url}`);
});
/**
* 往請求響應(yīng)頭中寫入響應(yīng)時(shí)間
*/
app.use(async (context, next) => {
// 請求之前記錄當(dāng)前時(shí)間
const start = Date.now();
// 等待上層執(zhí)行完成
await next();
// 響應(yīng)之后計(jì)算等待時(shí)間單位毫秒
const ms = Date.now() - start;
context.set('X-Response-Time', `${ms}ms`);
});
// 請求路由集合
const pets = {
'/about': context => {
context.response.type = 'html';
context.response.body = '<a href="/">關(guān)于頁面</a>';
},
'/login': context => {
context.response.type = 'html';
context.response.body = '<div>登錄頁面</div>';
},
'/reg': context => {
context.response.body = '注冊頁面';
},
'/mine': context => {
context.response.type = 'html';
context.response.body = '<div>個(gè)人中心</div>';
},
'/show/:name': (context, name) => {
context.response.type = 'html';
context.response.body = '<div>個(gè)人中心 ' + `${name}` + ' </div>';
}
};
// 添加路由
Object.keys(pets).forEach(function (key) {
app.use(_.get(key, pets[key]));
});
// 路由home路徑的get請求
router.get('/home', async (ctx, next) => {
ctx.body = 'we are at home!';
return next();
}, async (ctx, next) => {
ctx.body = 'home 2';
});
// 對(duì)應(yīng)HTTP對(duì)應(yīng)的動(dòng)作滞伟,all代表所有的請求方式
router
.get('/', async (ctx, next) => {
ctx.body = 'Hello World!';
})
.post('/users', async (ctx, next) => {
})
.put('/users/:id', async (ctx, next) => {
})
.del('/users/:id', async (ctx, next) => {
})
.all('/users/:id', async (ctx, next) => {
});
// 將路徑路由添加到app
app
.use(router.routes())
.use(router.allowedMethods());
app.use(async context => {
context.body = 'hello , index';
});
app.listen(3000, () => {
console.log('服務(wù)啟動(dòng)成功!');
});