視頻地址:www.cctalk.com/v/151149238…前端
在前面幾節中,咱們已經實現了項目中的幾個常見操做:啓動服務器、路由中間件、Get
和 Post
形式的請求處理等。如今你已經邁出了走向成功的第一步。node
目前,整個示例中全部的代碼都寫在 app.js
中。然而在業務代碼持續增大,場景更加複雜的狀況下,這種作法不管是對後期維護仍是對患有強迫症的同窗來講都不是好事。因此咱們如今要作的就是:『分梨』。數據庫
路由部分的代碼能夠分離成一個獨立的文件,並根據我的喜愛放置於項目根目錄下,或獨立放置於 router
文件夾中。在這裏,咱們將它命名爲 router.js
並將之放置於根目錄下。小程序
const router = require('koa-router')()
module.exports = (app) => {
router.get('/', async(ctx, next) => {
ctx.response.body = `<h1>index page</h1>`
})
router.get('/home', async(ctx, next) => {
console.log(ctx.request.query)
console.log(ctx.request.querystring)
ctx.response.body = '<h1>HOME page</h1>'
})
router.get('/home/:id/:name', async(ctx, next)=>{
console.log(ctx.params)
ctx.response.body = '<h1>HOME page /:id/:name</h1>'
})
router.get('/user', async(ctx, next)=>{
ctx.response.body =
` <form action="/user/register" method="post"> <input name="name" type="text" placeholder="請輸入用戶名:ikcamp"/> <br/> <input name="password" type="text" placeholder="請輸入密碼:123456"/> <br/> <button>GoGoGo</button> </form> `
})
// 增長響應表單請求的路由
router.post('/user/register',async(ctx, next)=>{
let {name, password} = ctx.request.body
if( name == 'ikcamp' && password == '123456' ){
ctx.response.body = `Hello, ${name}!`
}else{
ctx.response.body = '帳號信息錯誤'
}
})
app.use(router.routes())
.use(router.allowedMethods())
}
複製代碼
const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const app = new Koa()
const router = require('./router')
app.use(bodyParser())
router(app)
app.listen(3000, () => {
console.log('server is running at http://localhost:3000')
})
複製代碼
代碼看起來清爽了不少。後端
然而到了這一步,仍是不可以高枕無憂。router
文件獨立出來之後,應用的主文件 app.js
雖然暫時看起來比較清爽,但這是在只有一個路由,而且處理函數也很是簡單的狀況下。若是有多個路由,每一個處理函數函數代碼量也都繁複可觀,這就不是主管們喜聞樂見的事情了。微信小程序
接下來咱們對結構進行進一步優化。服務器
咱們把路由對應的業務邏輯也分離出來。微信
新建 controller
文件夾,增長一個 home.js
文件,並從 router.js
中提取出業務邏輯代碼。app
module.exports = {
index: async(ctx, next) => {
ctx.response.body = `<h1>index page</h1>`
},
home: async(ctx, next) => {
console.log(ctx.request.query)
console.log(ctx.request.querystring)
ctx.response.body = '<h1>HOME page</h1>'
},
homeParams: async(ctx, next) => {
console.log(ctx.params)
ctx.response.body = '<h1>HOME page /:id/:name</h1>'
},
login: async(ctx, next) => {
ctx.response.body =
` <form action="/user/register" method="post"> <input name="name" type="text" placeholder="請輸入用戶名:ikcamp"/> <br/> <input name="password" type="text" placeholder="請輸入密碼:123456"/> <br/> <button>GoGoGo</button> </form> `
},
register: async(ctx, next) => {
let {
name,
password
} = ctx.request.body
if (name == 'ikcamp' && password == '123456') {
ctx.response.body = `Hello, ${name}!`
} else {
ctx.response.body = '帳號信息錯誤'
}
}
}
複製代碼
修改 router.js
文件,在裏面引入 controler/home
:koa
const router = require('koa-router')()
const HomeController = require('./controller/home')
module.exports = (app) => {
router.get( '/', HomeController.index )
router.get('/home', HomeController.home)
router.get('/home/:id/:name', HomeController.homeParams)
router.get('/user', HomeController.login)
router.post('/user/register', HomeController.register)
app.use(router.routes())
.use(router.allowedMethods())
}
複製代碼
如此,將每一個路由的處理邏輯分離到 controller
下的獨立文件當中,便於後期維護。
目前的代碼結構已經比較清晰了,適用於以 node
做爲中間層、中轉層的項目。若是想要把 node
做爲真正的後端去操做數據庫等,建議再分出一層 service
,用於處理數據層面的交互,好比調用 model
處理數據庫,調用第三方接口等,而controller
裏面只作一些簡單的參數處理。
這一層的分離,非必需,能夠根據項目狀況適當增長,或者把全部的業務邏輯都放置於
controller
當中。
新建 service
文件夾,並於該文件夾下新增一個 home.js
文件,用於抽離 controller/home.js
中的部分代碼:
module.exports = {
register: async(name, pwd) => {
let data
if (name == 'ikcamp' && pwd == '123456') {
data = `Hello, ${name}!`
} else {
data = '帳號信息錯誤'
}
return data
}
}
複製代碼
// 引入 service 文件
const HomeService = require('../service/home')
module.exports = {
// ……省略上面代碼
// 重寫 register 方法
register: async(ctx, next) => {
let {
name,
password
} = ctx.request.body
let data = await HomeService.register(name, password)
ctx.response.body = data
}
}
複製代碼
下一節咱們將引入視圖層 views
,還會介紹使用第三方中間件來設置靜態資源目錄等。新增的部分前端資源代碼會讓咱們的用例更加生動,盡情期待吧。
下一篇:視圖nunjucks——Koa 默認支持的模板引擎
上一篇:iKcamp新課程推出啦~~~~~iKcamp|基於Koa2搭建Node.js實戰(含視頻)☞ HTTP請求
2019年,iKcamp原創新書《Koa與Node.js開發實戰》已在京東、天貓、亞馬遜、噹噹開售啦!