When to use query and params to get url data in express - node.js

It seems that /patient/123 and /patient?id=123 will both work fine at the backend of my application.
I could do req.param.id and do req.query.id as well.
But I'm getting confused on when to use then. What are the cases that you should use params and what are the cases that you should use query. Because in the answer here, j_mcnally only mentioned that they're interchangeable.
Url params and url path are somewhat interchangeable. People usually use url path for describing restful resources...
So what are the possible pros and cons of using them.

The query string is usually modifiers to the resource you're running, while the path should give just enough info to let your back-end indentify the data you're requesting.
/patients/123 - patients in this case would be the namespace, and 123 would be the identifier. You can also extend this with:
/patients/123/profile where profile would be an identifier for a pre-defined collection of data.
Query string usually offers fine-grained control over what and how your resource presents data, for example:
/patients/123?fields=firstname,lastname,age - This is pretty self-explanatory, but basically the query string in this case modifies what data is returned.
/patients?orderby=age&order=desc&fields=firstname,lastname&limit=25 - This query string modifies both how and what data is returned, and that's the purpose of the query string in RESTful API's.

Related

Difference between operators in a URL

What's the difference between using : and ? in a URL? For example /products/:id and /products?id=1? I am trying to get the values from the URL like this Product.findById (req.params.id) but I was wondering which one is most suitable. I know using : do I have to use req.params and ? req.query but I don't understand the difference between them, are they the same?
in my point of view, it is totally different if you are using RESTFUL API pattern
/products/:id called path parameters
The path parameters determine the resource you’re requesting for. Think of it like an automatic answering machine that asks you to press 1 for service, press 2 for another service, 3 for yet another service and so on.
Path parameters are part of the endpoint itself and are not optional
but query parameters
Technically, query parameters are not part of the REST architecture, and they used to help you completely understand how to read and use API’s Query parameters give you the option to modify your request with key-value pairs.
Having your parameters in the query is conceptually optional to the router, query parameters are more of properties and descriptions of the request itself, like when saying GET /users?sort=asc, in this case, the sort attribute was more of a description to the request and the request could complete the fetch without it, that might not always be the case, but a query parameter still describes its request even if it was mandatory.
On the other hand, URL parameters are part of the request itself, the URL without the parameter doesn't make sense, like GET /users/:userID, in this case, not supplying userID will supply unexpected data (A list of users for example) if it didn't break the router completely. URL parameters play part in defining the request rather than just describing it, and they can't be optional.

JSON Schema validator 'id' field

I am using a JSON Schema to validate a file. This is somehat similar to an XML XSD.
I have a few questions concerning the id field.
Does the schema still works without network connection ?
The URL in the id should be accessible from a web browser ? i.e. if 'id' = "https://example.com/question", does this mean that we should be able to access the schema from a browser by going to https://example.com/question ?
I am a bit lost on this subject. I know that it is best practice to have an id property as a unique identifier for every schema, and that this gets most useful when creating a complex schema with different schemas that reference each other.
But I am not sure if we need to assign a URL to the id field or not. And I'm also lost concerning the implication of having this URL for the schema.
Thank you very much for your help
Main purpose of id ($id since draft-06) is to organize scope for $ref resolving.
$id does not have to be an existing HTTP resource. Identified schema can be even defined in another one (example in spec test suite).
JSON Schema spec expects that validator should be able to resolve references based on $ids defined in current schema. Remote references should be also resolved, but there are no limitations on how exactly it should happen.
In many cases network interactions during validations are very unwanted due to high latency. Most implementations provide you a way to preload/define schema resources by $id explicitly before validation.
According to spec root schema SHOULD have $id which is an absolute URI, but whether or not it should be accessible with HTTP client is up to you and your validator.
$id is only defined to be an URI.
http://json-schema.org/draft-07/json-schema-core.html#rfc.section.8.2
See RFC-3986 Uniform Resource Identifier (URI): Generic Syntax
https://www.rfc-editor.org/rfc/rfc3986
"A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource."
A nice write-up by Daniel Messier provides a clear explanation of the nature of an URI - which can just be an URN - but may also be a valid URL
https://danielmiessler.com/study/url-uri/

Using Hashids to protect the id in database

People get the data from url like http://domain/api/user/1 and the 1 is the id(primary key) in the database. We want to avoid this to prevent people detect the ids.
Then I found Hashids which can encode/decode the id to string, the url may change to http://domain/api/user/D42dhDLdk
It is a wonderful solution at the first glance, however how to use it in the real application?
1 encode
When records are retrieved from the database, we should encode the id to string, which is the right place to do this job? The only right place I can thought is the deserialization of the records, for example, when you serve data of json, you can encode the related ids to string, but you have to make sure which fields should be encoded.
For example:
{user:{id:1,name:'xx',projects:[{id:1,name:'p1',id:2,name:'p2'}]},icon_id:1}}
The id of the user project and the icon_id should be encoded, there are no clear rules to abstract that.
2 decode
You have to decode the string to id when retrieve the data from db, I think we can do this in the route or controller layer, however there are still no clear rules to make a abstract middleware to hanlde this, since the encoded string may exist in the url or the query params.
I have not find any general solution from google, so I wonder how do you handle this kind of problem?
Update:
I am using Mysql, and Express with sequelzie as the ORM tool.

Web API - GET - passing in multiple parameters in this scenario

When I have this URI and pass in the PlayerCode: 12345, everything is good.
https://abc.com/teams/players/12345
But when I have a list of 9000 player codes how do I pass the specific list of order code list for a GET operation?
While this question -asked before,here - suggests "an" answer I am not sure if it is "the" answer. I am not sure if I should be going for something like :
https://abc.com/teams/players/?PlayerCodes=12345,23456,34567,45678....
and then have custom model binders to cater to the above.
Does passing in 9000 comma separated values in a URI make sense?
What would be the optimal solution for this scenario?
unfortunately, when you get into the realm of big numbers like 9000, query string parameters will not be sufficient. I assume you are running your solution in IIS or IIS express, both of which have character limits on the query string of somewhere around 2048. In this scenario you can either choose to do an HTTP POST and post a body of the playerId's for the players you need to retrieve, or you could rework your architecture a bit and break your GET calls up into acceptable sizes.

Looking up types from Freebase

I am trying to find a list of relevant types to a certain string from Freebase, lets say for example i enter Jordan, then i will have a list with types country, person, athlete .. etc.
I have found several ways for the query, for example:
First Query
trying to get the JSON fails, using:
$.getJSON('http://api.freebase.com/api/service/search?query=jordan',function (data) {
console.log(data);
});
There is another query that gives me better result, as i only get the types here but i also cannot get the JSON file from it.
Will appreciate any help.
Your problem has probably less to do with freebase and more to do the fact that you can't do cross domain http requests. You are requesting data from api.freebase.com but you are probably hosting this page in another domain.
You can use the JSONP mechanism to circumvent that restriction, here is some documentation:
http://api.jquery.com/jQuery.getJSON/
Read the section JSONP.
Another couple of points:
Are you trying to search for all entities that somehow match the word "jordan" or are you looking for exactly all the entities that are named "jordan" ? Your best bet is to use the /search API instead of /mqlread which is for structured database queries.
You are also using the legacy API that is deprecated. Here is some docs on the new API:
http://wiki.freebase.com/wiki/API
Here's how your request will look (note that you 'll need an API key for production):
https://www.googleapis.com/freebase/v1/search?query=jordan&mql_output=[{%22name%22%20:%20null,%22type%22:[]}]

Resources