Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express middleware access to req.params

I'd like to isolate a piece of code that would inspect either req.params or req.body for a value that is required on every request. What I'm finding is that if I try to access those values before app.use(app.router) then the request hasn't been parsed to include those objects. If I try to insert the middleware after app.use(app.router) then it gets skipped all together.

What can I do to work on these values in one place so that the work is ready to be used by downstream routes and models?

like image 272
Rob Wilkerson Avatar asked Mar 17 '14 19:03

Rob Wilkerson


People also ask

What objects does middleware have access to through its parameters?

Middleware functions are functions that have access to the request object ( req ), the response object ( res ), and the next function in the application's request-response cycle.

What is req params in Express?

The req. params property is an object that contains the properties which are mapped to the named route "parameters". For example, if you have a route as /api/:name, then the "name" property is available as req.params.name. The default value of this object is {}.

Which property of the request object provides the request METHOD in node JS?

The req object represents the HTTP request and has properties for the request query string, parameters, body, HTTP headers, and so on.

Which property of the request object in Express framework helps to retrieve the query parameters?

The req. query property is an object containing the property for each query string parameter in the route.


5 Answers

Just run the middleware inline with each route,

const middleware = (req, res, next) => {
    console.log(req.params.id);
    next();
};

app.get('/test/:id', middleware, (req, res) => {
    res.send('hi');
});
like image 155
mike james Avatar answered Oct 17 '22 21:10

mike james


You cannot do what you are trying to do. https://github.com/strongloop/express/issues/2088 explains this very clearly.

I have been trying to do what you are trying to do for some time, with no success. I finally tracked down this issue in github.

like image 27
CtheGood Avatar answered Oct 17 '22 20:10

CtheGood


Since my original answer won't obtain route parameters from the URL, e.g. /things/:foo (although it will get querystring and req.body params), it won't work the way we want. But another option would be to write a wrapper function that does what you need, and apply it to your route middleware:

function checkForParam (fn) {

    return function(req, res, next) {

       if (req.param('foo') != 'bar') {
          return res.send(403, 'No way Jose!');
       }

       fn (req, res, next);

    };

}

Then add routes with:

app.get('/things/:foo', checkForParam(function(req, res, next) {
  // your middleware code here
});

This will run the check and proceed to your custom route middleware only if it passes muster.

like image 41
sgress454 Avatar answered Oct 17 '22 21:10

sgress454


I like this way:

const controller = function (name, method) {
  return function (req, res) {
    // COERCE ID
    if (req.method === 'GET' || req.method === 'DELETE') {
      var _id = req.params && req.params._id || false
      if (/^[0-9a-f]{24}$/.test(_id)) {
        req.params._id = new ObjectID(_id)
      }
      else if (_id) {
        return res.status(404).send('Page not found.')
      }
    }
    require('./api/' + name + '.js')[method](req, res)
  }
}

Then:

app.get('/api/post/:_id', controller('posts', 'get'))
like image 1
Arthur Ronconi Avatar answered Oct 17 '22 19:10

Arthur Ronconi


Tried a simple core level workaround to get the URL params in router before proceeding into router

I need to validate the URL param id where it is an project id and to check respective user has access to it or not

And i don't want to use it in all routes as middleware so used split function to extract the project id which is in URL params

  router.use(apiauthenticated,(req,res,next)=>{
     try {  
          //req.params.projectid  
          let temp_projectid=req.originalUrl.split("/") //Getting all endpoints and params
          let last_element=temp_envid[temp_envid.length-1] //Get last element from array for URL params
          let projectid =last_element.includes("?") ? last_element.split("?")[0] : last_element //Returning URL params with or without query params
          if(projectid === "" ){
             //if it is null throwing error
             throw "Please provide required  projectid";
          }
          //Db validation here with projectid
          next();     
        } catch (error) {
            res.status(400).send(error);
            return null;
        }     
  })

apiauthenticated is the middleware to validate the API Key

Used last_element.includes("?") ? last_element.split("?")[0] : last_element for handling the query params

like image 1
Mohamed Sulaimaan Sheriff Avatar answered Oct 17 '22 21:10

Mohamed Sulaimaan Sheriff