Js全棧開發之koa2路由與mvc搭建初步

koa2路由與mvc搭建初步

接着上一篇《Js全棧開發之koa2初步搭建及基礎》來繼續學習koa2,上一篇只是簡單的瞭解一下koa原生的web服務搭建,實際的複雜項目需要很多中間件來提升開發效率,和減少編碼的複雜度,這篇主要涉及路由拆分與mvc項目結構的初步搭建,包含router路由層,controller控制層及service服務層。

1. koa-router路由

使用koa-router中間件來簡化路由的配置。先通過 npm管理工具進行安裝,先安裝koa-router路由包,再安裝koa-bodyparser參數解析包,安裝順序隨意,但代碼中koa-router和koa-bodyparser這兩個中間件的加載順序是有先後關係的,這段代碼中是bodyParser在前先加載。

1.1 安裝koa-router

npm install koa-router -save
npm install koa-bodyparser -save

1.2 示例代碼

使用示例代碼

const Koa = require('koa')
const router = require('koa-router')()
const bodyParser = require('koa-bodyparser')
const app = new Koa()

app.use(bodyParser())

// http://localhost:3000/
router.get('/', async(ctx, next) => {
  ctx.response.body = `<h1>index page</h1>`
})

// http://localhost:3000/home
router.get('/home', async(ctx, next) => {
  console.log(ctx.request.query)
  console.log(ctx.request.querystring)
  ctx.response.body = '<h1>HOME page</h1>'
})
// http://localhost:3000/home/1/dahlin
router.get('/home/:id/:name', async(ctx, next)=>{
  console.log(ctx.params)
  ctx.response.body = `Hello ${ctx.params.id}, ${ctx.params.name}`
})
// http://localhost:3000/404
router.get('/404', async(ctx, next) => {
  ctx.response.body = '<h1>404 Not Found</h1>'
})
// http://localhost:3000/user
router.get('/user', async(ctx, next)=>{
  ctx.response.body = 
  `
    <form action="/user/register" method="post">
      <input name="name" type="text" placeholder="請輸入用戶名:dahlin" value="dahlin"/> 
      <br/>
      <input name="password" type="text" placeholder="請輸入密碼:123456" value="123456"/>
      <br/> 
      <button>GoGoGo</button>
    </form>
  `
})
// http://localhost:3000/user/register
// 增加響應表單請求的路由
router.post('/user/register',async(ctx, next)=>{
  let {name, password} = ctx.request.body
  if( name == 'dahlin' && password == '123456' ){
    ctx.response.body = `Hello, ${name}!` 
  }else{
    ctx.response.body = '賬號信息錯誤'
  }
})

app.use(router.routes())
app.listen(3000, () => {
  console.log('server is running at http://localhost:3000')
})

1.3 postman測試

執行效果
路由執行效果截圖

2. mvc架構搭建

mvc的原理就不多說了,Java裏的Spring MVC,C#裏的Asp.Net MVC,Python裏的Django等都採用了MVC的架構,基本主流編程技術棧的web服務框架,基本全是MVC結構,架構設計也都大同小異,理論上只要掌握一種,其他的也能很快掌握。
下面舉例koa2的mvc結構,其實都是人爲的劃分目錄和拆分模塊。

2.1 mvc項目結構

先在項目根目錄下新建controller文件夾及service文件夾,之後在controller目錄下新建home.js文件,在service目錄下新建home.js文件。
並在根目錄下新建router.js文件,用以編寫拆分出的路由源碼。
簡單的mvc項目結構如下:

- controller
--- home.js
- service
--- home.js
- router.js
- app.js

2.2 路由拆分源碼

router.js中路由源碼。

const router = require('koa-router')()
const HomeController = require('./controller/home')
module.exports = (app) => {
  router.get( '/', HomeController.index )
  router.get('/home', HomeController.home)
  // http://localhost:3000/home/1/dahlin
  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())
}

2.3 控制器拆分源碼

controller.js控制器源碼。

const HomeService = require('../service/home')
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>Hello ${ctx.params.id}, ${ctx.params.name}</h1>`
  },
  login: async(ctx, next) => {
    ctx.response.body =
      `
      <form action="/user/register" method="post">
        <input name="name" type="text" placeholder="請輸入用戶名:dahlin" value="dahlin"/> 
        <br/>
        <input name="password" type="text" placeholder="請輸入密碼:123456" value="123456"/>
        <br/> 
        <button>提交</button>
      </form>
    `
  },
  register: async(ctx, next) => {
    let {
      name,
      password
    } = ctx.request.body
    let data = await HomeService.register(name, password)
    ctx.response.body = data
  }
}

2.4 服務層拆分源碼

service.js服務層源碼。

module.exports = {
    register: async(name, pwd) => {
      let data 
      if (name == 'dahlin' && pwd == '123456') {
        data = `Hello, ${name}!`
      } else {
        data = '賬號信息錯誤'
      }
      return data
    }
  }

2.5 啓動入口代碼

app.js 爲程序啓動入口代碼,類似Java中的main方法。

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')
})

總體來講,就是入口方法app.js調用router層中匹配的路由,router路由調用controller層中對應的方法,controller中的方法再調用service中的單一的業務邏輯功能,當然最後返回的響應還是在controller層中。這裏沒有用模板把視圖層從controller層拆分出來,視圖層的分離在下一篇中進行總結。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章