First published at: github.com/USTB-musion…

Writing in the front

Express is a concise and flexible Node.js Web application development framework that provides a series of powerful features to help you create a variety of Web and mobile applications. Rich HTTP shortcuts and arbitrary combinations of Connect middleware make it quick and easy to create robust, friendly apis.

This paper will summarize from the following parts:

  1. Implementation of routing
  2. Implementation of Middleware
  3. Built-in middleware implementation

Implementation of routing

Simply put, the method and path are matched and the corresponding callback function is executed. The following is an example of routing:

// Express is a function let express = require('./express-route') // Listener function let app = express() // RESTFUL apis perform resource processing according to different method names app.get('/name', (req, res) => { res.end('name') }) app.get('/age', (req, res) => { res.end('9') }) app.post('/name', (req, res) => {res.end('post name')}) // all matches all methods, * means matches all paths app. res) { res.end(req.method) }) app.listen(3000, () => { console.log('server start 3000') })Copy the code

As you can see from the above example, you can define an express-route.js file and expose the Express functions, get, POST, all, listen, etc., to run the above example. The code for express routing is as follows:

let http = require('http'); let url = require('url'); Function createApplication() {let app = (req, res) => { Let getMethods = req.method.tolowerCase (); let { pathname } = url.parse(req.url, true); for (let i = 0; i < app.routes.length; i++) { let {method, path, handler} = app.routes[i]; If ((method = = = getMethods | | method = = = 'all') && (path = = = the pathname | | path = = = '*')) {/ / perform corresponding callback after a successful match handler(req, res); End (' Cannot ${getMethods} ${pathName} ')} app.routes = []; All = function(path, handler) {let layer = {method: 'all', // all matches path, handler} app.routes.push(layer); } // http.methods can get all HTTP METHODS http.methods.foreach (method => {// convert the method name to lowercase method = method.tolocalelowerCase (); App [method] = function(path, handler) {let layer = {method, path, handler} app.routes.push(layer); // app.get = function(path, handler) {// let layer = {// method: 'get', // path, // handler // } // app.routes.push(layer); App.listen = function() {let server = http.createserver (app) server.listen(... arguments) } return app } module.exports = createApplication;Copy the code

By exposing a createApplication function and returning the app object. HTTP.METHODS can be used to obtain all HTTP METHODS, and the APP object defines listen, ALL, get, POST and other request METHODS. When the client requests, the routes are traversed, and when the reason is matched, the corresponding handler function is executed.

Implementation of Middleware

As shown in the figure above, middleware is a function that processes HTTP requests for specific tasks such as checking whether the user is logged in, checking whether the user has access rights, and how long it takes to execute a request. Its features are:

  • Requests and responses can be processed by one middleware and then passed to the next middleware
  • The next argument to the callback function accepts calls from other middleware
  • Middleware can be differentiated to return different execution based on the path

The following is a simple example of using Express middleware:

// Middleware use let express = require('./express-middleware.js'); let app = express(); Use ('/name', function(req, res, next) {res.setheader (' content-type ','text/ HTML; charset=utf-8'); console.log('middleware1'); Next ('middleware2')}) app.use('/', function(req, res, next) {console.log('middleware2'); next(); }) app.get('/name', (req, res, next) => { // res.setHeader('Content-Type','text/html; charset=utf-8'); Res. The end (' name '); Next (' name 'illegal)}) app. Get ('/age, (the req, res) = > {the console. The log (the req. Path); console.log(req.hostname); console.log(req.query); Res. The end (' age '); Use (function(err, req, res, next) {console.log(err) next()}) app.listen(3001, () => { console.log('server start 3001') })Copy the code

Looking at the example above, you can see that the app.use method calls the middleware, where next is a very important parameter. To run the above example, you can define an express-middware.js that implements the app.use method and, if you run next, invoke the next middleware. It works like this: Define a next function and an index value, and each time next is called, the index value increases by 1. If the current layer is equal to the item in routes, the match is successful. The simple code for implementing express middleware is as follows:

let http = require('http'); let url = require('url'); Function createApplication() {// Let app = (req, Res) => {let getMethods = req.method.tolowerCase (); let { pathname } = url.parse(req.url, true); // next let index = 0; Function next(err) {// If the array is iterated through and not found, If (index === app.routes. Length) {return res.end(' Cannot ${getMethods} ${pathName} ')} // The next layer is called each time the next method is called let { method, path, handler } = app.routes[index++]; If (err) {// If there is an error, go to error middleware. Error middleware has a feature, Handler (handler. Length === 4) {handler(err, req, res, next)} else {// If no match is found, pass err to next(err); / / to find the next layer judge}} else {/ / processing middleware if (method = = = 'middleware') {if (path = = = '/' | | path = = = the pathname | | pathname.startsWith(path + '/')) { handler(req, res, next); } else {// If this middleware does not match, proceed to the next middleware match next(); }} else {/ / processing route if ((method = = = getMethods | | method = = = 'all') && (path = = = the pathname | | path = = = '*')) {/ / After the match is successful, the corresponding callback handler(req, RES) is executed. } else { next(); }}}} // Next method in middleware next(); Res. end(' Cannot ${getMethods} ${pathName} ')} app.routes = []; App. use = function(path, handler) {if (typeof handler! == 'function') { handler = path; path = '/'; } let layer = {method = 'middleware'; 'Middleware ', path, handler} // Add middleware to the container app.routes.push(layer); Use (function(req, res, next) {let {pathname, query} = url.parse(req.url, true); let hostname = req.headers['host'].split(':')[0]; req.path = pathname; req.query = query; req.hostname = hostname; next(); }) // implement all method app.all = function(path, handler) {let layer = {method: 'all', // all matches path, handler} app.routes.push(layer); } // http.methods can get all HTTP METHODS http.methods.foreach (method => {// convert the method name to lowercase method = method.tolocalelowerCase (); App [method] = function(path, handler) {let layer = {method, path, handler} app.routes.push(layer); Function () {let server = http.createserver (app) server.listen() {let server = http.createserver (app) server. arguments) } return app } module.exports = createApplication;Copy the code

Implementation of built-in middleware

Express extends a number of built-in apis in the form of middleware. A simple example:

  app.use(function(req, res, next) {
    let { pathname, query } = url.parse(req.url, true);
    let hostname = req.headers['host'].split(':')[0];
    req.path = pathname;
    req.query = query;
    req.hostname = hostname;
    next();
  })
Copy the code

Req can package hostname, path, Query, hostname.

You can pay attention to my public account “Muchen classmates”, goose factory code farmers, usually record some trivial bits, technology, life, perception, grow together.