195

Is there a difference between obtaining QUERY_STRING arguments via req.query[myParam] and req.params.myParam? If so, when should I use which?

Pavindu
  • 2,684
  • 6
  • 44
  • 77

6 Answers6

366

Given this route

app.get('/hi/:param1', function(req,res){} );
// regex version
app.get(/^\/hi\/(.*)$/, function(req,res){} );
// unnamed wild card
app.get('/hi/*', function(req,res){} );

and given this URL http://www.google.com/hi/there?qs1=you&qs2=tube

You will have:

req.query

{
  qs1: 'you',
  qs2: 'tube'
}

req.params

{
  param1: 'there'
}

When you use a regular expression for the route definition, capture groups are provided in the array using req.params[n], where n is the nth capture group. This rule is applied to unnamed wild card matches with string routes

Express req.params >>

rofrol
  • 14,438
  • 7
  • 79
  • 77
ruffrey
  • 6,018
  • 3
  • 23
  • 19
201

req.params contains route parameters (in the path portion of the URL), and req.query contains the URL query parameters (after the ? in the URL).

You can also use req.param(name) to look up a parameter in both places (as well as req.body), but this method is now deprecated.

JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • Ah, ok, thanks, so both is provided by Express. And POST data I access via req.body.myParam? –  Jan 19 '13 at 19:41
  • 1
    Right. Which one to use depends upon what you're trying to do. – JohnnyHK Jan 19 '13 at 19:42
  • Also note: "Direct access to req.body, req.params, and req.query should be favoured for clarity - unless you truly accept input from each object." - express documentation – Ryan Q Sep 25 '13 at 06:09
  • 3
    `req.param` is now deprecated. Node suggests using `req.query` or `req.params` – SaiyanGirl Mar 13 '15 at 21:50
  • 3
    why deprecate it? what if we use params or query and then decide to change it to another? –  Jun 10 '15 at 02:00
  • @JohnnyHK can we use request.body instead of req.query or param as it is dreprecated? – Minakshi Apr 16 '20 at 06:58
83

request.params

Suppose you have defined your route name like this:

https://localhost:3000/user/:userId

which will become:

https://localhost:3000/user/5896544

Here, if you will print: request.params

{
userId : 5896544
}

so

request.params.userId = 5896544

so request.params is an object containing properties to the named route


request.query

The request.query comes from query parameters in the URL eg:

https://localhost:3000/user?userId=5896544 

request.query

{

userId: 5896544

}

so

request.query.userId = 5896544

Yogesh Umesh Vaity
  • 41,009
  • 21
  • 145
  • 105
Deeksha Sharma
  • 3,199
  • 1
  • 19
  • 16
9

You should be able to access the query using dot notation now.

If you want to access say you are receiving a GET request at /checkEmail?type=email&utm_source=xxxx&email=xxxxx&utm_campaign=XX and you want to fetch out the query used.

var type = req.query.type,
    email = req.query.email,
    utm = {
     source: req.query.utm_source,
     campaign: req.query.utm_campaign
    };

Params are used for the self defined parameter for receiving request, something like (example):

router.get('/:userID/food/edit/:foodID', function(req, res){
 //sample GET request at '/xavg234/food/edit/jb3552'

 var userToFind = req.params.userID;//gets xavg234
 var foodToSearch = req.params.foodID;//gets jb3552
 User.findOne({'userid':userToFind}) //dummy code
     .then(function(user){...})
     .catch(function(err){console.log(err)});
});
Animesh Singh
  • 8,382
  • 1
  • 17
  • 20
1

I want to mention one important note regarding req.query , because currently I am working on pagination functionality based on req.query and I have one interesting example to demonstrate to you...

Example:

// Fetching patients from the database
exports.getPatients = (req, res, next) => {

const pageSize = +req.query.pageSize;
const currentPage = +req.query.currentPage;

const patientQuery = Patient.find();
let fetchedPatients;

// If pageSize and currentPage are not undefined (if they are both set and contain valid values)
if(pageSize && currentPage) {
    /**
     * Construct two different queries 
     * - Fetch all patients 
     * - Adjusted one to only fetch a selected slice of patients for a given page
     */
    patientQuery
        /**
         * This means I will not retrieve all patients I find, but I will skip the first "n" patients
         * For example, if I am on page 2, then I want to skip all patients that were displayed on page 1,
         * 
         * Another example: if I am displaying 7 patients per page , I want to skip 7 items because I am on page 2,
         * so I want to skip (7 * (2 - 1)) => 7 items
         */
        .skip(pageSize * (currentPage - 1))

        /**
         * Narrow dont the amound documents I retreive for the current page
         * Limits the amount of returned documents
         * 
         * For example: If I got 7 items per page, then I want to limit the query to only
         * return 7 items. 
         */
        .limit(pageSize);
}
patientQuery.then(documents => {
    res.status(200).json({
        message: 'Patients fetched successfully',
        patients: documents
    });
  });
};

You will noticed + sign in front of req.query.pageSize and req.query.currentPage

Why? If you delete + in this case, you will get an error, and that error will be thrown because we will use invalid type (with error message 'limit' field must be numeric).

Important: By default if you extracting something from these query parameters, it will always be a string, because it's coming the URL and it's treated as a text.

If we need to work with numbers, and convert query statements from text to number, we can simply add a plus sign in front of statement.

Mile Mijatović
  • 2,948
  • 2
  • 22
  • 41
1

I just want to add that if you're coming from axios, (GET/POST) you make query/url params (readable with req.query) available via the config:

axios.post('/users', {...data}, {
  headers: {...anyHeaders},
  params: {uid: `${uid}`}
})

And you make path/route variables (readable with req.params) available via the path:

axios.get(`/users/${uid`}, {
  headers: {...anyHeaders}
})

Let me also add this, the names used to read query params on the server must match those from the client. This is not the case with path variables where any name can be used on the server, provided that portion of the path/route is available (basically does a substitution - kinda like how react-router does it: /path/:variable).

kawerewagaba
  • 1,107
  • 2
  • 15
  • 21