Many languages have frameworks that make it easier to develop and maintain projects. JS has popular frameworks like Vue, React, Angular, etc. Node.js is no exception, and it has several frameworks to help us develop Node.js projects.

At present, popular Node.js frameworks include Express, Koa and egg.js. No matter which Node.js framework is implemented based on middleware, the implementation of middleware needs to follow the Onion model.

The onion model

In an abstract way, to go through the center of an onion, one layer must first go in through the skin into the center, and then go out through the skin from the center. There is a characteristic here: as many layers of skin as you enter, you must exit through the skin. First into the epidermis, then out of the epidermis, this structure is in line with the stack structure of the first out of the principle.

In node. js framework, onion skin can be defined as middleware:

  • The process of going from the outside in to the center is a key wordnext();
  • And from the inside out is the completion of each middleware, into the next layer of middleware, until the last layer.

Here’s a quick look at the Express framework.

Express

Express is a framework for HTTP services in Node.js, and the best way to understand a framework is

  • To understand its key functions
  • What is the problem that we derive it to solve

To learn more about its key Features, go to the Express web site and check out its Features. These core Features are designed to make it easier to write HTTP services in a concise way, which greatly reduces the development burden and allows us to get started quickly.

Some of the Features:

  • Route: Routes are separated into modules
  • request/responseThe simplicity of attributes allows us to use the corresponding attributes directly without having to go through the transformation.
    • request:pathname,query
    • response:send(),json(),jsonp()
  • Middleware (next())
    • Better organization of process code
    • Asynchrony breaksExpressOnion model

Express reinvented the rock-paper-scissors game

The code for the game.js game module and the index.html page remains unchanged. You can check out the node.js web version of the rock-paper-Scissors mini-game or clone it on Github.

NPM I Express: NPM I Express

const fs = require('fs');
const express = require('express');

const game = require('./game');
let playerWon = 0; // The number of wins

const app = express();

// Routing function, separate the corresponding routing function as module processing, then can also be put in other files
// Set the route of the /favicon.ico path through app.get
//. Get means method is get, so you can use post, delete, etc. This capability is ideal for creating REST services
app.get('/favicon.ico'.function (request, response) {
  // Status (200) replaces writeHead(200); end();
  // response.writeHead(200);
  // response.end();
  response.status(200);
  return;
})
// Open the page index.html
app.get('/'.function (request, response) {
  // fs.createReadStream(__dirname + '/index.html').pipe(response);
  // The send interface determines the type of value you are passing, or text/ HTML
  // Buffer is treated as a download, and the HTML file needs to be marked with 'UTF-8'
  response.send(fs.readFileSync(__dirname + '/index.html'.'utf-8'))})// Next () synchronous is fine, but once asynchrony is introduced, the onion model is broken
app.get('/game'.function (request, response, next) {
    if (playerWon >= 3) {
      response.status(500);
      response.send('I won't play any more! ');
      return;
    }
    // Execute subsequent middleware through next
    next();
    // This location will be executed when the subsequent middleware execution is complete
    if(response.playerWon) { playerWon++; }},// Get the player's actions
  function (request, response, next) {
    // Express does some processing on request, so you can get query parameters directly
    // const query = querystring.parse(parsedUrl.query);
    // const playerAction = query.action;
    const query = request.query;
    const playerAction = query.action;
    response.playerAction = playerAction;
    // Execute subsequent middleware through next
    next();
  },
  function (request, response) {
    // Mount some parameters via response
    let playerAction = response.playerAction;
    // Execute the game logic
    const gameRes = game(playerAction);
    // Return to the header first
    // response.writeHead(200);
    response.status(200);
    // Returns different instructions for different game results
    if (gameRes == 0) {
      // response.end(' Tie! ');
      response.send('the draw! ');
    } else if (gameRes == 1) {
      response.send('You won! ');
      // Player win count +1
      // playerWon++;
      response.playerWon = true;
    } else {
      response.send('You lost! ');
    }
  }
)
app.listen(3000);
Copy the code

Here’s the code