Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

A: hi! ~ Hello, everyone, I am YK bacteria 🐷, a front-end microsystem ✨, like to share their small knowledge 🏹, welcome to follow me 😘 ~ [wechat account: YK2012YK2012, wechat official account: ykyk2012]

We started with Express. Today we are going to learn about Express middleware. We are going to introduce some built-in middleware, and then we will use some third-party middleware in our demo.

Example 1.

Requirement: Output request logs

app.get("/".(req, res) = > {
  console.log(req.method, req.url, Date.now());
  res.send("get /");
});
Copy the code

If we wanted to output a request log for each route, we could encapsulate it in a function

const myLooger = (req) = > {
  console.log(req.method, req.url, Date.now());
};
app.get("/".(req, res) = > {
  myLooger(req);
  res.send("get /");
});
Copy the code

But we don’t want to modify every route. We can use middleware.

// req request object
// res response object
// next Next middleware
app.use((req, res, next) = > {
  console.log(req.method, req.url, Date.now())
  // Give up execution and continue to match execution
  next()
})

app.get("/".(req, res) = > {
  res.send("get /");
});
Copy the code

The order of middleware is important [top-down] [routing] is also a kind of middleware]

2. Concept analysis

2.1 Middleware and AOP

The biggest feature of Express, and one of its most important designs, is the middleware.

Add some new functionality without modifying the original code

An Express application is made up of a lot of middleware.

Express middleware is similar to AOP in that faceted programming requires several steps to extend or handle functionality without modifying your own code

  • Aspect Oriented Programming (AOP) is Aspect Oriented Programming
    • The code of logging, performance statistics, security control, transaction processing, exception handling and so on are separated from the code of business logic. By separating these behaviors, we hope to separate them into non-guiding methods of business logic, and then change these behaviors without affecting the code of business logic
    • AOP can be used to isolate each part of the business logic, so as to reduce the degree of coupling between each part of the business logic, improve the reusability of the program and improve the efficiency and maintainability of development

Summary: Adding/subtracting one or more features in an existing code application does not affect the original functionality during the application lifecycle or horizontal flow.

2.2 Middleware in Express

In Express, the middleware is a function that accesses the request object, the response object, and the next method

In a middleware function, you can perform any of the following tasks

  • Execute any code
  • Modify therequestresponseResponse object [same life cycle]
  • The request response period ends
  • Call the next middleware

[Note] If the current middleware function does not end the request-response cycle, next() must be called to pass full control to the next middleware function. Otherwise, the request will be suspended

3. Use in detail

In Express applications can use the following types of middleware

  • Application-level middleware
  • Routing level middleware
  • Error handling middleware
  • Built-in middleware
  • Third-party middleware

3.1 Application level middleware

Do not care about the request path

app.use((req, res, next) = > {
  console.log("Time".Date.now());
  next();
});
Copy the code

Qualified request path

app.use('/user/:id'.(req, res, next) = > {
  console.log("Request Type", req.method); // GET
  next();
});
Copy the code

Define request method + Request path

app.get('/user/:id'.(req, res, next) = > {	
  res.send('Hello World')});Copy the code

Multiple processing functions

app.use(
  "/user/:id".(req, res, next) = > {
    console.log("Request URL", req.originalUrl);
    next();
  },
  (req, res, next) = > {
    console.log("Request Type", req.method); next(); });Copy the code

Define multiple processing middleware for the same path

app.get(
  "/user/:id".(req, res, next) = > {
    console.log("ID", req.params.id);
    next();
  },
  (req, res, next) = > {
    res.send("User Info"); next(); }); app.get("/user/:id".(req, res, next) = > {
  console.log("123");
  // res.end(req.params.id);
});
Copy the code

To skip the rest of the middleware functionality from the router middleware stack, call next(‘route’) to pass control to the next route

Next (‘route’) is only valid in intermediate functions loaded using app.method () or router.method ()

This example shows a middleware substack that handles GET requests to the /user/:id path

app.get(
  "/user/:id".(req, res, next) = > {
    if (req.params.id === "0") next("route");
    else next();
  },
  (req, res, next) = > {
    res.send("regular"); }); app.get("/user/:id".(req, res, next) = > {
  res.send("special");
});
Copy the code

Middleware can also be declared reusable in arrays.

This example shows an array with a middleware substack that handles GET requests to the /user/:id path

function logOriginalUrl(req, res, next) {
  console.log("Request URL", req.originalUrl);
  next();
}
function logMethod(req, res, next) {
  console.log("Requset Type", req.method);
  next();
}
const logStuff = [logOriginalUrl, logMethod];

app.get("/user/:id", logStuff, (req, res, next) = > {
  res.send("User Info");
});
Copy the code

3.2 Routing level middleware

Creating a router file

router.js

const express = require('express')

1. Create a route instance
// The routing instance is equivalent to a Mini Express instance
const router = express.Router()

2. Configure routes
router.get('/user'.(req, res) = > {
  res.send('get /user')
})

router.post('/user/:id'.(req, res) = > {
  res.send(`post /user/${req.params.id}`)})// 3. Export the route instance
// export default router
module.exports = router

// 4. Integrate routing into Express instances [mount]
Copy the code

app.js

const express = require("express");
const router = require('./router')

const app = express();
const port = 3000; / / the default 3000

// 4. Mount the route
app.use(router)
app.use('/yk', router)

app.listen(port, () = > {
  console.log(`Server running at http://localhost:${port}/ `);
});
Copy the code

3.3 Error handling middleware

Error handling [Call next(err)]

Defines an error-handling middleware function with four parameters

The error-handling middleware is typically mounted after all the middleware

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

Error-handling middleware always takes four parameters and must provide them, even if next does not need to specify them, otherwise it will be interpreted as regular middleware and will not be able to handle errors

If anything is passed to the next() function (except ‘route’), Express treats the current request as an error and skips all remaining non-error-handling routes and middleware functions

app.get("/todos".async (req, res, next) => {
  try {
    const db = await getDb();
    res.status(200).json(db.todos);
  } catch (err) {
    // Skip all remaining error-free routes and intermediate functionsnext(err); }}); app.use((err, req, res, next) = > {
  console.log("Error", err);
  res.status(500).json({
    error: err.message,
  });
});
Copy the code

Handle 404 [Route mismatch]

It is usually configured to handle the contents of 404 after all routes

app.use((req, res, next) = > {
  res.status(404).send("404 Not Found.");
});
Copy the code

3.4 Built-in Middleware

  • express.json()Parsing the content-type forapplication/jsonFormat request body
  • express.urlencoded()Parsing the content-type forapplication/x-www-form-urlencodedFormat request body
  • express.raw()Parsing the content-type forapplication/octet-streamFormat request body
  • express.text()Parsing the content-type fortext/plainFormat request body
  • express.static()Host static resource files

3.5 Third-party Middleware

Early Express had a lot of middleware built in. Express later removed the built-in middleware after 4.x and officially offered the functional middleware as a package. The goal is to keep Express minimalist and flexible, allowing developers to use it as they see fit.

www.expressjs.com.cn/resources/m…

Reference video: Express Tutorial (Basic + Practical + Principle)