REST and Filtering records - web-services

I currently have a .NET method that looks like this - GetUsers(Filter filter) and this is invoked from the client by sending a SOAP request. As you can probably guess, it takes a bunch of filters and returns a list of users that match those filters. The filters aren't too complicated, they're basically just a set of from date, to date, age, sex etc. and the set of filters I have at any point is static.
I was wondering what the RESTful way of doing this was. I'm guessing I'll have a Users resource. Will it be something like GET /Users?fromDate=11-1-2011&toDate=11-2-2011&age=&sex=M ? Is there a way to pass it a Filter without having to convert it into individual attributes?
I'm consuming this service from a mobile client, so I think the overhead of an extra request that actually creates a filter: POST filters is bad UX. Even if we do this, what does POST filters even mean? Is that supposed to create a filter record in the database? How would the server keep track of the filter that was just created if my sequence of requests is as follows?
POST /filters -- returns a filter
{
"from-date" : "11-1-2011",
"to-date" : "11-2-2011",
"age" : "",
"sex" : "M"
}
GET /Users?filter=filter_id
Apologies if the request came off as being a little confused. I am.
Thanks,
Teja

We are doing it just like you had it
GET /Users?fromDate=11-1-2011&toDate=11-2-2011&age=&sex=M
We have 9 querystring values.
I don't see any problem with that

The way I handle it is I do a POST with the body containing the parameters and then I return a redirect to a GET. What the GET URL looks like is completely up to the server. If you want to convert the filter into separate query params you can, or if you want to persist a filter and then add a query param that points to the saved filter that's ok too. The advantage is that you can change your mind at any time and the client doesn't care.
Also, because you are doing a GET you can take advantage of caching which should more than make up for doing the extra retquest.

Related

Django (GET) - Is it posible to pass multiple values in only one parameter, instead of multiple parameters called the same

I'm developing an web app with Django to query and download data from multiple weather stations. It's almost everything good but something that I don't like it's that when I filter by stations, the form passes them to the URL like this:
https://my-server/stations?station_name=1&station_name=2&station_name=3
And since the number of selected stations can reach more than 250 (this added to the fact that spatial data are also passed in the URL as coordinates, polygons...), I would like to know if there is any way to obtain the "station_name" parameter in a list format like this or similar, for me to later divide it in my views.py:
https://my-server/stations?station_name=1%3B2%3B3
On the other hand, I'm not sure if there are any contraindications when generating too long URLs, if not I have no problem maintaining the current format, but otherwise I would like to find a solution.
Thanks in advance
Edit: If it helps, I'm using the Select2MultipleWidget widget for this field.

How to build query form to request AWS CloudSearch?

I have a SearchDomain on AWS CloudSearch. I know all the defined facets names.
I would like to build a web query form to use it, but I want to add my categories values (facets) on the side, like it is done on Amazon webstore
The only way I have to get facets values is to make a query (params query) and in the answer will contain facets linked to my query results.
Is there a way to fetch all the facet.FIELD possible values to build the query form ?
If not (as read here), how to design a form using facets ?
You could also use the matchall keyword in a structured query. Also, since you don't need the results you can pass size=0 so you only get the facets which will reduce latency.
/2013-01-01/search?q=matchall&q.parser=structured&size=0&facet.field={sort:'count',size:100}

Passing List of Integers to GET REST API

I wanted to fetch the List of Entities from database at Front end.
So I have written POST REST HTTP call in Spring MVC.
But I read the HTTP documentation which says whenever you have to retrieve data from database prefer GET call.
So, Is it there is any I can replace the POST call to GET call from angular JS and pass list of Integers.
But, GET HTTP has many drawbacks like : the length of URL is limited.Considering the case where we have to fetch 1000 entities from database.
Please suggest me the possible way to get the entities or write GET REST API in Spring MVC for list of integers(refers to ID's of Entities).
For Example : Consider there are 100 books in book table, But I want only few books, say id : 5,65,42,10,53,87,34,23.
Thats why I am passing this List of Id's in a List of Integer in POST call.
Currently stuck how to convert this to GET call. In Short, how to pass List of Integers through GET REST call.
I prefer a variant through HTTP path variable for your problem, because of in REST ideology a resource ID is passed after a resource name 'http://../resource/id' and HTTP parameters are used for filtering.
Through HTTP parameters
If you need to pass your ids through HTTP parameters, see an axample below:
Here is your Spring MVC controller method:
#RequestMapping(value = "/books", params = "ids", method = RequestMethod.GET)
#ResponseBody
Object getBooksById_params(#RequestParam List<Integer> ids) {
return "ids=" + ids.toString();
}
And you can make a call using next variants:
http://server:port/ctx/books?ids=5,65,42
http://server:port/ctx/books?ids=5&ids=65&ids=42
Also take a look this discussion: https://stackoverflow.com/a/9547490/1881761
Through HTTP path variables
Also you can pass your ids through path variable, see an example below:
#RequestMapping(value = "/books/{ids}", method = RequestMethod.GET)
#ResponseBody
Object getBooksById_pathVariable(#PathVariable List<Integer> ids) {
return "ids=" + ids.toString();
}
And your call will be look like this: http://server:port/ctx/books/5,65,42
Pros of GET HTTP call : It is always used for retrieval of Data.(From this perspective : we should implemented for each and every and retrieval)
Through HTTP parameters
If you need to pass your ids through HTTP parameters, see an axample below:
Here is your Spring MVC controller method:
#RequestMapping(value = "/book", params = "ids", method = RequestMethod.GET)
#ResponseBody
Object getBooksById_params(#RequestParam List<Integer> ids) {
return "ids=" + ids.toString();
}
It works fine but for exceptional case : say URI is above 2048 characters. It means there are many Id's in the list(eg : 1000)
then its throws an exception :
return 414 (Request-URI Too Long)
which is http://www.checkupdown.com/status/E414.html
After some research MY UNDERSTANDING is : The HTTP protocol does not place any a priori limit on the lenght of a URI. Servers MUST be able to handle the URI of any resources they serve, and SHOULD be able to handle URIs of unbounded length if they provide GET-based forms that could generate such URIs. A server SHOULD return 414(Request_URI Too Long) status if a URI is longer than the server can handle.
I have also gone through sites like to get the GET URI length :
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2.1
So conclusion, is stick to POST call when there can be variable URI length at runtime for not getting such exception[return 414 (Request-URI Too Long)]
Alternatively, to allow for complex queries you'll need to give the query its own rest language. So to create a query you POST to /library/query then you edit it with things like POST /library/query/12345 with data {id:34} and then you execute the query with GET /library/books?query=12345
Simply you can call list like this:
***/users?id=1&id=2
If you want to read entities from your API you have to use a GET call.
The better way to get them all is to use a query params as filter.
REST DESIGN cannot retrieve more than one entity each time by id.
An example:
GET /library/books/58731 -> returns only one book identified by 58731
GET /library/books?numPages>70 returns all the books with more than 70 pages
I think that If you need to retrieve a lot of books because they have some logic that all matches, try to put it as a queryString.
Another example:
GET /library/books?stored>20150101 returns all the books added to library on 2015
If you give us more information about the collection and the requirements we will answer more directly.

Correct way to query the server for all records, but filter the cached ones in Ember.js

I need to use the filter method in order to prevent unsaved new records (!isNew) from being listed/shown before being saved.
So, The official Ember.js guide, says, the filter method signature is filter (type, query, filter) and that the query is an optional argument.
The thing is, When I don't specify the query, I don't get any results, and nothing is shown.
Further digging, And I found out (correct me if I am wrong), That the filter method filters the cached records, So, This means I have to query the back-end the first time I visit the route?
My question is, Is this the correct way to do it? I feel that there is something wrong with just leaving the query argument blank, Or HAVING to put a blank argument in the first place!
Here is my Route (which works perfectly and as expected by the way) :
SalesRepsRoute = Ember.Route.extend
model: ->
# the query left blank in order to get all salesReps from the server.
#store.filter('sales-rep', {} ,(sr) ->
!sr.get('isNew')
)
Thanks in advance, And please let me know if I should post any more code/info .
filter is meant to be used for querying the store, but in the event that you'd like to trigger a call to the server you can specify a hash as the second parameter.
If you feel hacky (which you shouldn't) about it, you can just call find before it and exclude the hash in the filter call. find will asynchronously call your backend and the filter will stay up to date with records as they are added to the store.
#store.find('sales-rep')
#store.filter('sales-rep', (sr) ->
!sr.get('isNew')
)

Find model returns undefined when trying to get the attribute of a model by first finding the model by another attribute?

I would like to do something like:
App.Model.find({unique_attribute_a: 'foo'}).objectAt(0).get('attribute_b')`
basically first finding a model by its unique attribute that is NOT its ID, then getting another attribute of that model. (objectAt(0) is used because find by attribute returns a RecordArray.)
The problem is App.Model.find({unique_attribute_a: 'foo'}).objectAt(0) is always undefined. I don't know why.
Please see the problem in the jsbin.
It looks like you want to use a filter rather than a find (or in this case a findQuery). Example here: http://jsbin.com/iwiruw/438
App.Model.find({ unique_attribute_a: 'foo' }) converts the query to an ajax query string:
/model?unique_attribute_a=foo
Ember data expects your server to return a filtered response. Ember Data then loads this response into an ImmutableArray and makes no assumption about what you were trying to find, it just knows the server returned something that matched your query and groups that result into a non-changable array (you can still modify the record, just not the array).
App.Model.filtler on the other hand just filters the local store based on your filter function. It does have one "magical" side affect where it will do App.Model.find behind the scenes if there are no models in the store although I am not sure if this is intended.
Typically I avoid filters as it can have some performance issues with large data sets and ember data. A filter must materialize every record which can be slow if you have thousands of records
Someone on irc gave me this answer. Then I modified it to make it work completely. Basically I should have used filtered.
App.Office.filter( function(e){return e.get('unique_attribute_a') == 'foo'}).objectAt(0)
Then I can get the attribute like:
App.Office.filter( function(e){return e.get('unique_attribute_a') == 'foo'}).objectAt(0).get('attribute_b')
See the code in jsbin.
Does anyone know WHY filter works but find doesn't? They both return RecordArrays.