javascript - Specify Express middleware that always runs at the end? - Stack Overflow

Does express provide a way to specify that a middleware always runs at the end of the chain?I want to c

Does express provide a way to specify that a middleware always runs at the end of the chain?

I want to create a pair of middleware functions, one at the start, and one at the end, which gather up analytics about the call.

I know I can do something like this:

app.use(entry);

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

app.use(exit);

Where entry() and exit() are my middleware.

However, there are two things I don't like about this solution. First, is that next() has to be called or else the exit() middleware won't be used.

The other is that I would prefer to instead build a Router that can be used as one piece and just work. Something like:

// 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();
});

Being able to bundle it all up in to one thing that always runs would make it a lot more usable.

Does express provide a way to specify that a middleware always runs at the end of the chain?

I want to create a pair of middleware functions, one at the start, and one at the end, which gather up analytics about the call.

I know I can do something like this:

app.use(entry);

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

app.use(exit);

Where entry() and exit() are my middleware.

However, there are two things I don't like about this solution. First, is that next() has to be called or else the exit() middleware won't be used.

The other is that I would prefer to instead build a Router that can be used as one piece and just work. Something like:

// 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();
});

Being able to bundle it all up in to one thing that always runs would make it a lot more usable.

Share Improve this question edited Jul 4, 2022 at 6:48 peteb 19.5k9 gold badges57 silver badges66 bronze badges asked Nov 27, 2017 at 20:06 samanimesamanime 26.6k17 gold badges97 silver badges150 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 10

Since the res object in Express wraps http.ServerResponse, you can attach a listener for the 'finish' event in a middleware. Then when the response is "finished", exit() will be called as soon as the event fires.

// 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

// 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();
});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744307194a4567773.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信