background



The figure above shows a typical front-end and back-end structure of a Web application developed using Node.js. Here are the functions of the Node service layer and some advantages and disadvantages of using Node.js.

Node service layer functions:

  1. The traditional approach of request proxy is that the back end provides APIS for the front end to call directly, but the back end gradually tends to be servitization, and the direct call faces the following problems:

    • Cross domain

    • The data need a second processing

    • When the back-end service is deployed on the Intranet, the front-end service cannot be invoked directly

  2. routing

  3. Template rendering

Advantages of using Node.js:

  1. The front and back ends are separated to save the cost of communication and joint adjustment.

  2. The ecosystem is prosperous, and there are many third-party modules. Rational use can greatly improve the development efficiency.

  3. High performance in high concurrency scenarios, suitable for Web applications.

Disadvantages of using Node.js:

  1. Js is a weakly typed language with low reliability, and potential problems are hard to find.

  2. Not suitable for CPU intensive applications such as video codec.

Introduction to the Node.js framework

When it comes to Node.js development, Express and Koa are two big frameworks that are hot right now.

Express has been born for a long time. It is a minimalist and flexible Web application development framework based on Node.js platform. It is mainly based on Connect middleware and encapsulates functions such as routing and view processing.

Koa is a relatively young framework redeveloped by the original Express team based on the new ES6 features. It is mainly based on CO middleware. The framework itself does not contain any middleware, and many functions need to be solved by third-party middleware. The solution to “callback hell” and troublesome error handling was a hit with developers. Koa is currently officially version 1.2.4, and the Koa team has stated that version 2.0 will not be released until Node supports async/await.

The sample

Hello World

Creating a basic Web service is simple and written in much the same way, with the biggest difference being that routing processing Express is self-integrated, whereas Koa requires middleware to be introduced.



// Express
var express = require('express')
var app = express()

app.get('/'.function (req, res) {
  res.send('Hello World! ')
})

app.listen(3000)Copy the code


// Koa
var koa = require('koa')
var route = require('koa-route')

var app = koa()

app.use(route.get('/'.function *(a){
  this.body = 'Hello World'
}))

app.listen(3000)Copy the code

Views

Express itself integrates view functionality, provides consolidated.js functionality, supports almost all JavaScript template engines, and provides a convenient way to set up views. Koa needs to introduce co-views middleware.



// Express
var express = require('express')
var app = express()

app.set('views', __dirname + '/views')
app.set('view engine'.'jade')

app.get('/'.function (req, res) {
  res.render('index', {
    title: 'bilibili'})})Copy the code


// Koa
var koa = require('koa')
var route = require('koa-route')
var views = require('co-views')

var render = views(__dirname + '/views', {
  default: "jade"
})

var app = koa()

app.use(route.get('/'.function *(a) {
  this.body = yield render('index', {
    title: 'bilibili'}})))Copy the code

HTTP Request

Both frameworks encapsulate HTTP Request objects, but Koa V1 uses this instead of Express req and RES.



// Express
var app = require('express')()

app.get('/room/:id'.function (req, res) {
  console.log(req.params)
})

// Retrieving POST data requires body-parser middleware
var bodyParser = require('body-parser')
app.use(bodyParser.json())
app.post('/sendgift'.function (req, res) {
  console.log(req.body)
})Copy the code


// Koa
var app = require('koa') ()var route = require('koa-route')

app.use(route.get('/room/:id'.function *(a) {
  console.log(this.req.query)
}))

// Co-body middleware is required to obtain POST data
var parse = require('co-body')
app.use(route.post('/sendgift'.function *(a) {
  var post = yield parse(this.request)
  console.log(post)
}))Copy the code

Differences between Express and Koa

Asynchronous flow control

Express uses callback to handle asynchro, Koa V1 uses generator and Koa V2 uses async/await. The following is a comparison of four asynchronous process controls in JS: callback, Promise, Generator and async/await. Generator and async/await use synchronous writing to deal with asynchracy. Significantly better than callback and promise, async/await is semantically more powerful than Generator.



// callback
var api1 = 'https://anapioficeandfire.com/api/characters/583'
var api2 = 'https://anapioficeandfire.com/api/characters/584'

function fetchData (a) {
  $.ajax({
    type: 'GET',
    url: api1,
    dataType: 'json',
    success: function (data1) {
      $.ajax({
        type: 'GET',
        url: api2,
        dataType: 'json',
        success: function (data2) {
          console.log(`${data1.name} and ${data2.name} are two characters in Game of Thrones`)
        }
     })
    }
  })
}

fetchData()Copy the code


// Promise
var api1 = 'https://anapioficeandfire.com/api/characters/583'
var api2 = 'https://anapioficeandfire.com/api/characters/584'

function fetchData (a) {
  fetch(api1).then(res1 => {
    res1.json().then(data1 => {
      fetch(api2).then(res2 => {
        res2.json().then(data2 => console.log(`${data1.name} and ${data2.name} are two characters in Game of Thrones`))
      })
    })
  })
}

fetchData()Copy the code


// generator
var api1 = 'https://anapioficeandfire.com/api/characters/583'
var api2 = 'https://anapioficeandfire.com/api/characters/584'

function *fetchData (a) {
  var name1 = yield request(api1)
  var name2 = yield request(api2)
  console.log(`${name1} and ${name2} are two characters in Game of Thrones`)
}

function request (url) {
  fetch(url).then(res => res.json()).then(data => it.next(data.name))
}

var it = fetchData()
it.next()Copy the code


// async/await
var api1 = 'https://anapioficeandfire.com/api/characters/583'
var api2 = 'https://anapioficeandfire.com/api/characters/584'

async function fetchData (a) {
  var name1 = await request(api1)
  var name2 = await request(api2)
  console.log(`${name1} and ${name2} are two characters in Game of Thrones`)
}

function request (url) {
  return fetch(url).then(res => res.json()).then(data => data.name)
}

fetchData()Copy the code

Error handling

Express uses callback to catch exceptions, but Koa uses try catch to better handle exception catching if deep level exception catching is not possible.



// Express callback
app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke! ')})Copy the code


// Koa generator
app.use(function *(next) {
  try {
    yield next
  } catch (err) {
    this.status = err.status || 500
    this.body = { message: err.message }
    this.app.emit('error', err, this)}})Copy the code


// Koa async/await
app.use(async (ctx, next) => {
  try {
    await next()
  } catch (err) {
    ctx.status = err.status || 500
    ctx.body = { message: err.message }
    ctx.app.emit('error', err, this)}})Copy the code

conclusion

Express

Advantages: Linear logic, business logic is subdivided and simplified in the form of middleware. A request is processed by a series of middleware and then responded to the user, which is clear and clear. Disadvantages: It combines business logic based on callback, which is too much nested in complex business logic and difficult to catch exceptions.

Koa

Advantages: Firstly, with CO and generator, asynchronous process control and exception catching are well solved. Second, Koa removed the Router, View, and other features built into Express, making the framework itself lighter. Cons: Relatively small community.