3

I did a google search, but I could not find what I really need. I need to query an API, which have the same route, but with different parameters.

Example:

router.get('/items/:query, function(){})

In this case, I would search for all items

router.get('/items/:id, function(){})

Here, I would look for a specific item

Daniel Swater
  • 237
  • 1
  • 6
  • 19

2 Answers2

2

At the core of your issue is that you are trying to specify two different resources at the same location. If you design your API to adhere to restful principles you'll see why that's not a wise choice. Here are two good starting points:

https://en.wikipedia.org/wiki/Representational_state_transfer

http://www.restapitutorial.com/lessons/whatisrest.html

In restful api's the root resource represents the item collection:

/api/items

...and when you specify an id that indicates you want only one item:

/api/items/abc123

If you really still want to accomplish what you asked in your question you'll need to add a url parameter like /items/query?query=true or /items/abc123?detail=true but this will be confusing to 99% of web developers who ever look at your code.

Also I'm not sure if you really meant this, but when you pass a variable named "query" to the server that seems to indicate that you're going to send a SQL query (or similar data definition language) from the client into the server. This is a dangerous practice for several reasons - it's best to leave all of this type of code on your server.

Edit: if you really absolutely positively have to do it this way then maybe have a query parameter that says ?collection=true. This would at least be understood by other developers that might have to maintain the code in future. Also make sure you add comments to explain why you weren't able to implement rest so you're not leaving behind a bad reputation :)

Graham
  • 7,431
  • 18
  • 59
  • 84
  • You're right, I'd do it another way, but that's what needs to be done :( – Daniel Swater Aug 05 '17 at 17:07
  • Then you'll need to use query parameters as I described to flag the difference between the two types of request. I guess you could also use http headers too. No matter what, there are no ways to accomplish what you've asked for without a flag being read somewhere in node. – Graham Aug 05 '17 at 17:10
0

The issue is that without additional pattern matching there isn't a way Express will be able to distinguish between /items/:query and /items/:id, they are the same route pattern, just with different aliases for the parameter.

Depending on how you intend to structure your query you may want to consider having the route /items and then use query string parameters or have a separate /items/search/:query endpoint.

Stuart Wakefield
  • 6,294
  • 24
  • 35