{%hackmd BJrTq20hE %}
第 14 屆 iThome 鐵人賽 (2022)
在app.js中引用Koa,啟動應用:
import Koa from 'koa'
import ip from 'ip'
import conf from './config'
import router from './router'
import middleware from './middleware'
import './mongodb'
const app = new Koa()
middleware(app)
router(app)
app.listen(conf.port, '0.0.0.0', () => {
console.log(`server is running at http://${ip.address()}:${conf.port}`)
})
Koa 是以 Node.js平台為基礎的Web開發架構,由Express原班人馬打造,致力於成為Web應用和API開發領域中更小且更加富有表現力、更穩固的基礎。透過async函數Koa幫使用者捨棄回乎函數,並增強錯誤處理。Koa並沒有綁定任何中介匴體,而是提供了一套優雅的方法幫助使用者快速撰寫伺服器端應用程式。
Koa把很多async函數組成一個處理鏈,每個async函數都可以做一些自己的事情,然後用await next()
來呼叫下一個async函數。這裡把每個async函數稱為middleware,這些middleware可以組合起來,完成很多有用的功能。Koa透過 app.use(function)將指定的中介軟體方法曾嫁到此應用程式,透過app.use()註冊的async函數會傳入ctx 和 next 參數,設定傳回內容:
import path from 'path'
import bodyParser from 'koa-bodyparser'
import staticFiles from 'koa-static'
import Rule from './rule'
import Send from './send'
import Auth from './auth'
import Log from './log'
import Func from './func'
export default app => {
//快取攔截器
app.use(async (ctx, next) => {
if (ctx.url == '/favicon.ico') return
await next()
ctx.status = 200
ctx.set('Cache-Control', 'must-revalidation')
if (ctx.fresh) {
ctx.status = 304
return
}
})
// 日志中介軟體
app.use(Log())
// 資料傳回的封裝
app.use(Send())
// 方法封裝
app.use(Func())
//權限中介軟體
app.use(Auth())
//post請求中介軟體
app.use(bodyParser())
//靜態檔案中介軟體
app.use(staticFiles(path.resolve(__dirname, '../../../public')));
// 規則中介軟體
Rule({
app,
rules: [{
path: path.join(__dirname, '../controller/admin'),
name: 'admin'
},
{
path: path.join(__dirname, '../controller/client'),
name: 'client'
}
]
})
// 增加錯誤的監聽處理
app.on("error", (err, ctx) => {
if (ctx && !ctx.headerSent && ctx.status < 500) {
ctx.status = 500
}
if (ctx && ctx.log && ctx.log.error) {
if (!ctx.state.logged) {
ctx.log.error(err.stack)
}
}
})
}
程式中註冊了快取、記錄檔、許可權、post請求、靜態檔案、規則的中介軟體。呼叫app.use()的順序決定了middleware的順序。如果一個middleware沒有呼叫await next()
,後續的middleware就不再執行。舉例來說,若記錄檔中介軟體中有乎叫await next()
,則會繼續執行後續的中介軟體:
今天設定了server端的Middleware和app的主要程式,如同django的setting,這些在Server端的實現是不可或缺的,明天會再處理前端的部分。