Thursday, July 7, 2016

NodeJS choosing between req.params and req.query, and when to use them both.

req.params.memberId

actual url:
    http://example.com/member/thisGoesToParam

nodejs's routing: 
    http://example.com/member/:memberId

req.params.memberId == "thisGoesToParam"


req.query.memberId
actual url:
    http://example.com/member?memberId=thisGoesToQuery

nodejs's routing: 
    http://example.com/member

req.query.memberId == "thisGoesToQuery"



req.params is most often used since it can directly/explicitly identify a resource right in the URL itself, and it's SEO-friendly. Search engines prefer URLs that has no question marks in them, clean URLs, req.params can facilitate clean URL.


req.query is mostly used on searching or paging. Anything that are extra to the identifier, goes to req.query. An example, getting the list of person (uses paging since there are too many persons in a country) from a country should better use req.query instead of req.param.


actual url:
    http://example.com/country/PH/person?page=1

routing: 
    http://example.com/country/:countryCode/person

req.params.countryCode == "PH"
req.params.page == 1

that might return:

{
 country: "Philippines"
 persons: ["Schwarzenegger", "Zach"]
}


Anything that goes to req.params are called resource identifier, meaning even how many times the url with embedded resource is called/submitted to, result is always the same. REST has a terminology for that, idempotent. Idempotent meaning, when something is called/submitted to a url with a primary key, the result of calling/submitting to a URL should be always the same even how many times it is called/submitted to.

Parameters that goes to req.params returns idempotent result. While parameters that goes to req.query returns non-idempotent result, as req.query's result today would not be same as req.query's result tomorrow, later or any point in time


Let's say later there are new persons added to a country, the country identifier (req.params.countryCode) will always return idempotent result, same country even how many times it is called. While with req.query.page, it returns non-idempotent result, a value passed to req.query even it's the same might not be the same(say page number 1 is called/refreshed on the browser many times) depending on when the url is called/submitted.

http://example.com/country/PH/person?page=1

So even we use the same Country and same Page, although the country's parameter always return the same result(Philippines), the page's parameter might return different results depending on when the url is called/submitted.

{
 country: "Philippines"
 persons: ["Adams", "Applegate", "Ashley"]
}


It's much better to use req.params, not only it is SEO-friendly for search engines, in code it's also easy to spot the required parameters(mostly primary key) as they are explicitly part of the url itself.


routing: 
    http://example.com/country/:countryCode/person

actual url: 
    http://example.com/country/PH/person


To access countryCode from req.params. Simply read it from: req.params.countryCode


If a country REST API (that fetches the country name and its people) uses req.query instead of req.params, the REST's URL would have a routing design like this:

http://example.com/country/person 


The URL is not so intuitive, some non-native English speaker might think if "person" is a country code.

Note that question marks can't be included on node.js's routing, so the consumer of the REST's URL would have to guess what is the name of the country parameter for the country, is it countryCode? is it countryId? req.query parameters have to be always documented, while req.params is so intuitive it doesn't even need documentation.


Happy Coding!

No comments:

Post a Comment