可以在 Context 的實(shí)例上獲取到當(dāng)前請(qǐng)求的 Request( ctx.request ) 和 Response( ctx.response ) 實(shí)例。
框架提供了一個(gè) Controller 基類(lèi),并推薦所有的 Controller 都繼承于該基類(lèi)實(shí)現(xiàn)。這個(gè) Controller 基類(lèi)有下列屬性:
框架提供了一個(gè) Service 基類(lèi),并推薦所有的 Service 都繼承于該基類(lèi)實(shí)現(xiàn)。 Service 基類(lèi)的屬性和 Controller 基類(lèi)屬性一致,訪(fǎng)問(wèn)方式也類(lèi)似
一個(gè)中間件是一個(gè)放置在 app/middleware 目錄下的單獨(dú)文件,它需要 exports 一個(gè)普通的 function,接受兩個(gè)參數(shù):
// app/middleware/error_handler.js
module.exports = () => {
return async function errorHandler(ctx, next) {
try {
await next();
} catch (err) {
// 所有的異常都在 app 上觸發(fā)一個(gè) error 事件,框架會(huì)記錄一條錯(cuò)誤日志
ctx.app.emit('error', err, ctx);
const status = err.status || 500;
// 生產(chǎn)環(huán)境時(shí) 500 錯(cuò)誤的詳細(xì)錯(cuò)誤內(nèi)容不返回給客戶(hù)端,因?yàn)榭赡馨舾行畔?
const error = status === 500 && ctx.app.config.env === 'prod'
? 'Internal Server Error'
: err.message;
// 從 error 對(duì)象上讀出各個(gè)屬性,設(shè)置到響應(yīng)中
if (status === 422) {
ctx.body = {
code: ctx.ERROR_CODE,
data: error,
msg: '參數(shù)錯(cuò)誤'+status
};
}
if (status === 500) {
ctx.body = {
code: 500,
data: '',
msg: '服務(wù)端錯(cuò)誤-----'+error
};
}
ctx.status = 200;
}
};
};復(fù)制代碼
在應(yīng)用中使用中間件
在應(yīng)用中,我們可以完全通過(guò)配置來(lái)加載自定義的中間件,并決定它們的順序。
如果我們需要加載上面的 gzip 中間件,在 config.default.js 中加入下面的配置就完成了中間件的開(kāi)啟和配置:
// 加載 errorHandler 中間件 config.middleware = ['errorHandler']復(fù)制代碼