iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ 程式碼分層

iKcamp發表於2018-01-03

視訊地址:www.cctalk.com/v/151149238…

iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ 程式碼分層

文章

在前面幾節中,我們已經實現了專案中的幾個常見操作:啟動伺服器、路由中介軟體、GetPost 形式的請求處理等。現在你已經邁出了走向成功的第一步。

目前,整個示例中所有的程式碼都寫在 app.js 中。然而在業務程式碼持續增大,場景更加複雜的情況下,這種做法無論是對後期維護還是對患有強迫症的同學來說都不是好事。所以我們現在要做的就是:『分梨』。

分離 router

路由部分的程式碼可以分離成一個獨立的檔案,並根據個人喜好放置於專案根目錄下,或獨立放置於 router 資料夾中。在這裡,我們將它命名為 router.js並將之放置於根目錄下。

修改路由 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())
  }
複製程式碼

修改 app.js

  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 層

我們把路由對應的業務邏輯也分離出來。

新增 controller/home.js

新建 controller 資料夾,增加一個 home.js 檔案,並從 router.js 中提取出業務邏輯程式碼。

  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

修改 router.js 檔案,在裡面引入 controler/home

  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 裡面只做一些簡單的引數處理。

分離 service 層

這一層的分離,非必需,可以根據專案情況適當增加,或者把所有的業務邏輯都放置於 controller 當中。

新建 service/home.js

新建 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
    }
  }
複製程式碼

修改 controller/home.js

// 引入 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|基於Koa2搭建Node.js實戰(含視訊)☞ 程式碼分層

iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ 程式碼分層

上一篇:iKcamp新課程推出啦~~~~~iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ HTTP請求

推薦: 翻譯專案Master的自述:

1. 乾貨|人人都是翻譯專案的Master

2. iKcamp出品微信小程式教學共5章16小節彙總(含視訊)


iKcamp|基於Koa2搭建Node.js實戰(含視訊)☞ 程式碼分層

2019年,iKcamp原創新書《Koa與Node.js開發實戰》已在京東、天貓、亞馬遜、噹噹開售啦!

相關文章