Search code examples
javascriptnode.jsexpressgoogle-analyticsanalytics

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


I aim to send an analytics event for each route in my API. As opposed to saving an event with the entire full route that was called, I want to save the base url as the event and the parameters of the route as variables of the event. For example, when saving an analytics event...

Not this:

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

But this:

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

I'd like to have a global function that gets the parameters from the request variable, however, if you do this on a higher level (not route level)

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

myWrapperFunction will detect anything after /api/user_routes as parameters. From my experiments, I was only able to successfully detect the actual parameters inside a specific route function. However, that approach requires me to either edit each route function or wrap it like so...

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));

Is there a way to detect the actual parameters of the route without actually going into the function itself? Or is this a limitation on express because it won't know the specifics of the route until it finds the first matching option traversing down the routes?

Edit If there is no way to know the parameters before express matches the specific route: is there a function that you can run before executing the route function that will tell you which route will be matched and will specify the parameters?

Welcome all comments!


Solution

  • Found a way to do it after the call is made by overwriting the response.json function

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