Node.js express - 无需进入路由功能即可获取路由参数以进行快速分析跟踪

Node.js express - get route params without going into the route function for quick analytics tracking

我的目标是为我的 API 中的每条路线发送一个分析事件。与使用调用的整个完整路线保存事件相反,我想将基础 url 保存为事件,并将路线参数保存为事件的变量。例如,在保存分析事件时...

不是这个:

{
  event_title: "API User Event"
  category: "domain.com/api/user_routes/route_1/value_of_param_one"
}

但是这个:

{
  event_title: "API User Event"
  category: "domain.com/api/user_routes/route_1"
  params: {
     param_one: "value_of_param_one"
  }
}

我想要一个从请求变量获取参数的全局函数,但是,如果您在更高级别(而不是路由级别)执行此操作

app.use('/api/user_routes/*', myWrapperFunction)

myWrapperFunction 将检测 /api/user_routes 之后的所有内容作为参数。根据我的实验,我只能成功检测到特定路由函数内的实际参数。但是,这种方法要求我要么编辑每个路由函数,要么像这样包装它...

router.get('/route_1/:param_one', (req, res) => Utility.analyticsEvent(userController.routeOneFunction, req, res));

router.get('/route_2/:param_one', (req, res) => Utility.analyticsEvent(userController.routeTwoFunction, req, res));

router.get('/route_3/:param_one', (req, res) => Utility.analyticsEvent(userController.routeThreeFunction, req, res));

有没有办法在不实际进入函数本身的情况下检测路由的实际参数?或者这是对 express 的限制,因为它在找到第一个遍历路线的匹配选项之前不知道路线的细节?

Edit 如果无法知道 express 匹配特定路由之前的参数:是否有一个函数可以 运行 在执行路由函数之前会告诉你匹配到哪条路由,会指定参数吗?

欢迎大家评论!

我认为一种方法是编写如下所示的中间件。

// This will get executed before every request. As we'll add this with app.use() with top level middlewares

function customMiddleware (req, res, next) {
   let url = req.baseUrl;
   // some if else logic to re-route

   if( url.includes('/api/user_routes')) {
     let urlSplit = url.split();
     if( url[urlSplit.length() - 1] == 'param_one' ) {
       res.redirect('/api/user_routes/route_1') 
     }
     else if(url[urlSplit.length() - 1] == 'param_tow' ) {
       res.redirect('/api/user_routes/route_1') 
     }
     // and so on

   } else {
      // executes other middleware or go to matching route
      next()
   }
}

app.use(customMiddleware)

找到了方法通过覆盖response.json函数

调用之后
app.use(function (req, res, next) {
  var json = res.json;
  res.json = function (body) {
      // Send analytics event before returning response     
      try { 
        // Routes that don't need to be tracked with analytics
        let notIncludeRoutes = [
          "some_not_tracked_route"
        ];
        let route = req.baseUrl + req.route.path;

        if(notIncludeRoutes.indexOf(route) === -1) {
          // Track route and params
          let route_params = res.req.params;
          Utility.analyticsEvent(route, route_params);
        }
      } catch(error) {
        // Don't block call if there was an error with analytics, but do log it
        console.log("ANALYTICS ERROR: ", error);
      }

      json.call(this, body);
  };
  next();
});