Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make optional params name in express route?

Here is below my code of route:-

app.get('/server/lead/get/:id?', leadCtrl.get);
app.get('/server/lead/filter/:filterQuery', leadCtrl.get);

As you see above i am using different route to access same controller method leadCtrl.get.

Now, i want something like route app.get('/server/lead/get/:id?:filter?', leadCtrl.get);. So, i can get params either req.params.id or req.params.filter but only one at a time.

like image 706
vineet Avatar asked Dec 02 '25 09:12

vineet


1 Answers

What you asked in the question is not possible in the form that you describe it.

Now, i want something like route app.get('/server/lead/get/:id?:filter?', leadCtrl.get);. So, i can get params either req.params.id or req.params.filter but only one at a time.

Your router would have no way to differentiate those two parameters. If it got a request to /server/lead/get/X then what is X? A filter or an ID?

Your options

You have few solutions here:

  1. You can either keep using two routes like you did before.

  2. You can use a common parameter for both cases as Robert explained in the comments.

  3. Or you can use what seems to me the perfect solution for your use case - named query parameters - just use a route /server/lead/get and use query parameters to pass id and the filter.

Example URLs:

  • /server/lead/get?id=xxx
  • /server/lead/get?filterQuery=xxx

You will only have to make sure in your handler that only one of those two are set at a time with something like:

if (req.query.id && req.query.filterQuery) {
  // respond with error
}

You can even mix the two if you have app.get('/server/lead/get/:id?') route you can have the id in the route and filterQuery as a query parameter. Now the URLs would be:

  • /server/lead/get/xxx (for id)
  • /server/lead/get?filterQuery=xxx (for filter)

For more info see: http://expressjs.com/en/api.html#req.query

Better way

If you follow some REST conventions then you can use:

  • app.get('/server/lead/:id') for one object with id (not optional)
  • app.get('/server/lead') for a list of objects (with optional filterQuery passed as a query parameter)

That way you would always know that when you access:

  • /server/lead/xxx - then it's one object with ID = xxx
  • /server/lead - then it's a list of any objects
  • /server/lead?filterQuery=xxx - then it's a list of objects that match the query

If you follow the REST conventions for things like this instead of inventing your own, it would be much easier for you to design the routes and handlers, and it would be much easier for other people to use your system.

You may also want to use plural /server/leads instead of /server/lead which is common with REST. That way it will be more obvious that leads is a list and leads/id is one of its elements.

For more info see:

  • https://en.wikipedia.org/wiki/Representational_state_transfer
  • http://www.restapitutorial.com/lessons/whatisrest.html
  • https://spring.io/understanding/REST
like image 74
rsp Avatar answered Dec 03 '25 23:12

rsp