指定总是在最后运行的 Express 中间件?

sam*_*ime 3 node.js express

是否express提供了一种方法来指定中间件始终运行在链的末端?

我想创建一对中间件函数,一个在开始,一个在结束,用于收集有关调用的分析。

我知道我可以做这样的事情:

app.use(entry);

app.get("/some-endpoint", (req, res, next) => {
  res.send("hello").end();
  next();
});

app.use(exit);
Run Code Online (Sandbox Code Playgroud)

entry()exit()是我的中间件。

但是,我不喜欢此解决方案的两件事。首先,next()必须调用它,否则exit()将不会使用中间件。

另一个是我更愿意构建一个Router可以作为一个整体使用并且可以正常工作的。就像是:

// MyRouter.js
const router = () => Router()
  .use(entry)
  .use(exit);
export default router;

// myServer.js
import router from './MyRouter.js';
import express from 'express';

const app = express();
app.use(router());

app.get("/some-endpoint", (req, res) => {
  res.send("hello").end();
});
Run Code Online (Sandbox Code Playgroud)

能够将它全部捆绑到一个始终运行的东西中将使其更有用。

pet*_*teb 5

由于resExpress 中的对象 wraps http.ServerResponse,您可以在中间件中为'finish'事件附加一个侦听器。然后当响应“完成”时,exit()将在事件触发后立即调用。

// analyticMiddleware.js
const analyticMiddleware = (req, res, next) => {
    // Execute entry() immediately
    // You'll need to change from a middleware to a plain function
    entry()

    // Register a handler for when the response is finished to call exit()
    // Just like entry(), you'll need to modify exit() to be a plain function
    res.once('finish', () => exit)

    // entry() was called, exit() was registered on the response return next()
    return next()
}

module.exports = analyticMiddleware
Run Code Online (Sandbox Code Playgroud)
// myServer.js
import analytics from './analyticMiddleware.js';
import express from 'express';

const app = express();
app.use(analytics);

app.get("/some-endpoint", (req, res) => {
  res.send("hello").end();
});
Run Code Online (Sandbox Code Playgroud)