How return the total entries in our JSON API if we use pagination by Link Header - api

I start implement a REST API. I have a request doing on a resource with multiple entries. To implement the pagination, I do like Github choose implement it.
I define a HTTP Header Link where I add the next/previous/first/last link.
Link: <https://api.github.com/repos?page=3&per_page=100>; rel="next",
<https://api.github.com/repos?page=50&per_page=100>; rel="last"
In my body there are only my entries and nothing else. But Now I want know how entries there are in total. I can't do a multiplication between number of page and per_page entries, because the result is not exact.
So how can I do to return this number to entries ? I think add a new HTTP Header in my answer X-total-entries. But I don't know if there are better technique or not.

When I try to decide whether to put some data into the headers or into the body, I ask myself if it is a feature of the application or of the protocol? In your case, is the pagination a feature of the application? Is the user aware what page he is looking at? Is the total number of items displayed to the user? If the answer is yes, then I would put the information into the body. Then the body becomes not just a list of items, but a representation of a page, with all the information and controls needed to display it. Only if the pagination is a internal protocol detail would I consider putting the links and the item count into the header. I know this may sound a rather abstract way of thinking, but if the pagination details need to bubble up all the way to the top of the application, there is little real benefit in separating this information from the body and putting it into the headers.

Related

REST Fetching data with GET not possible due to exceed header size limit

I am having a dilema. I need to fetch data for some products by Id, these products which are selected can vary from a couple to thousands.
I see and tested that GET is not possible due to exceeding the HeaderSizeLimit of 8192.
I had discussions with colleagues and changed to POST and the ids are in the body. Everything works but have a lot of discussions about this. Have you encountered something like this? What was your approach?
First question for me is, do you really pass all those ids in a single request? How is this list of IDs generated in the first place? Could the server know this list in advance?
For example, if the list of IDs is obtained by doing a search query on the same server, perhaps that search query can already emit the list of entities.
I find that in most cases this can be avoided, but there's some exceptions.
If you find that you can't avoid this, I would suggest you use the new http QUERY method instead of of POST, but POST should be fine too as a fallback.

How to Collect dijit/form/combobox Selected Values in Repeat Control

An XPage is used to display the number of points a person has collected, and the number of points remaining (see below).
I have a repeat control which gets a collection of documents meeting a specific criteria. The last column in the control contains 5 digit/form/comboboxes, which are displayed or hidden, according to the number of fields on each document that contain data.
The layout contains gift cards worth a certain amount of points, and the person can select how many of each gift card they want. eg.
Company Available in Values of Points Required Quantity Requested
The Quantity Requested column contains the digit/form/comboboxes. As the person selects values in the checkbox, I want the number of points remaining to be recalculated.
The onChange event of the digit/form/comboboxes calls a function in an Output Script which calls an RPC, which in turn calls an SSJS function. The SSJS function cycles through the documents displayed in the repeat control, gathering the points required information. I then wanted it to also grab the Quantity Requested. I understand from a previous posting that because of the way the digit/form/combox is rendered, I can only get the value using CSJS with dijit.byId and perhaps putting the value in a hidden field and retrieving it from there.
I can't seem to wrap my head around how I will do this when the repeat control will make it possible for there to be many combobox1 and combobox2, etc.
The XPage is not bound to a form, because all the items are just calculated on the fly and then discarded.
What is the best way to do this?
The JSON RPC service can't interact with any changes made in the browser, see https://www.intec.co.uk/json-rpc-service-component-tree-manipulation-openlog/. This could be the cause of your problems.
You may be able to get around it by triggering a partial refresh (POST) before calling the JSON RPC. In theory that might work, because the component tree (server-side map of the XPage) would get updated by the partialRefreshPost and the updates picked up by the JSON RPC. It's possible though that the Restore View picks up a version of the XPage other than the one for the browser, I don't know. I've never investigated that.
It's been a while since I've worked with server java script, I have been doing it the managed bean way with ActionListeners. If you have the data in the UI, then can you avoid server side processing and do it client side?
You can also use the DOM XSP Object like XSP.setSubmittedValue to have a key value pair sent with your post request to the server side, you can only have one... it can be JSON or any other value you set it to from the client side javascript.
I figured out how to do this. If anyone wants the code, let me know and I'll provide it.

Github API Conditional Requests with paging

Context: let's say we want to retrieve whole list of Starred repositories by given User periodically (ones per day, hour or few minutes).
There are at least 2 approaches to do that:
execute GET to https://api.github.com/users/evereq/starred and use Url with rel='next' in 'Link' Response Headers to get next page Url (we should do that till we get no "next" page in response, mean that we reach the end). Seems that is recommended approach (by Github).
iterating 'page' parameter (from 1 to infinite) using GET to https://api.github.com/users/evereq/starred?page=XXX till you get 0 results in response. Ones you get 0 results, you finish (not recommended because for example instead of page numbers Github can move to "hash" values. Github already did it for some API operations.).
Now, let's say we want to make sure we use Conditional Requests (see https://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requests) to save our API usage limits (and traffic, trees in the world, etc.).
So we add for example 'If-None-Match' to our Requests Headers and check if response Status is 304 (Not Modified). If so, it means that nothing was changed from our last request. That works OK.
The issue however that what we have in 1) and 2) above, related to the way how we detect when to stop is NOT working anymore when you use Conditional Requests!
I.e. with approach 1), you don't get Link Response Headers at all when you use Conditional Requests.
So you will need to execute one more request with page bigger than page for which you already have ETag and see that it return 0 results and than you know you are done. That way you basically "waste" one request to Github API (because it miss Conditional Requests Headers).
Same with approach 2), you basically have 0 responses in every request with status 304... So again, to know you are done, you need to make at least one additional request which do return 0 results.
So the question is: when we do conditional requests with the fact that Github API does not send back Link Response Header (at least with queries using ETag which result Status 304) how could we know when to stop paging? Is it a bug in Github API implementation OR I miss something?
We don't know maximum page number, so to get when to stop we should execute one more "waste" request and check if we get 0 results back!
I also can't found how to query Github for total count of starred repositories (so I can calculate how many pages I should iterate in advice), same as responses does not include something like "X-Total-Count" so I know when to stop using simple math for pages count.
Any ideas how to save that one ('end') request and still use Conditional Requests?
If you do one request per day, it's OK to accept such waste, but what if you do such request ones per minute? You will quickly use all your API usage Limits!
UPDATE
Well, after a few more tests, I see now following "rule" (can't however found it anywhere in the docs, so note sure if its rule or just assumption): if user star something new, result for EVERY requested page contains different ETag value compared to previous and does not have status 304 anymore! That means that it's enough to just request first page and check for status. if its 304 (not modified), we do NOT need to check next pages, ie we are DONE as nothing was changed in any page. Is it correct approach or just coincidence?
We indeed return pagination relations in the Link response header when the content has changed 1. Since we don't support a since parameter for that call, you'll need to sort by most recent results and maintain a client-side cursor for the last known ID or timestamp (based on your sort criteria) and stop paging when it shows up in your paginated results. Conditional requests will just let you know if Page 1 has changed.
We haven't settled on a way to return counts on our listing methods, but a really low-tech solution is to set the page size to 1, grab the rel=last Link relation and check its page parameter value.
Hope that helps.

Specify items per page

I'm trying to query Picasa Web Albums to pull album/photo data (obviously!) however initially I only need to pull the first 4 photos. Is there any way to limit a particular field or specify the items per page?
I've already accomplished something similar with Facebook's Graph API however I'm unable to find anything similar for Picasa. The only items I can find related to limiting the response is specifying which fields, but nothing related to the number of rows.
Use max-results argument. See doc here.
https://developers.google.com/picasa-web/docs/2.0/reference#Parameters

Designing an efficient rest API

I'm trying to design a REST API over HTTP. I am totally new to this, so please tell me if any of my assumptions or ideas are just plain wrong.
The domain is minimalistic. I have a database of Products and for each Product there is an associated Image. As I see it, I can design my API in one of two ways:
I can bundle each image with its product and represent them as one resource. The cons of this api would be that every time you PUT or GET a product, you have to send the image over the wire, even if you don't specifically need to read or change the image. As of my understanding, it would not be RESTful to not PUT or GET a complete representation of a resource. Also, client-side caching of images would be of no use in this scenario.
I can model Products and Images as two different resources. When you GET a Product, it will contain an image_id which can be used to GET an Image. This model would require two HTTP Requests. One to GET the Product and one to GET its corresponding Image. Not so bad maybe, but what if I want to display a list of all Products along with their Images? Then I suddenly have a bunch of HTTP Requests. While using SSL, I guess this could create a performance issue. Good thing though, is that the consumer of my API could choose to cache images client-side.
So, how can I model my API to be both RESTful and efficient?
It's good that you're thinking about the data model.
Related to that, REST doesn't specify or imply that the data model must be completely de-normalized.
Typically, when GETing a resource, you'd receive a packet of information that also includes URL references to other related resources, like a product image. It could also include a reference to a product category, a product manufacturer, and so on. Each might be URLs, or IDs that you could derive URLs from. A message like this:
{
"id": 123456,
"description" : "Your basic paperweight",
"category" : { id: 17717, "name" : "Home furnishings" },
"manufacturer": { id : 78783, "name" : "Boeing" },
"price" : 1.99,
"imageId" : 109101
}
...might imply URLs like this:
http://api.mycompany.com/product/123456
http://api.mycompany.com/category/17717
http://api.mycompany.com/manufacturer/78783
http://api.mycompany.com/image/109101
...and note that the full representation of the linked-to resources, like category, manufacturer and so on, is not transmitted with the original resource. This is a partially de-normalized data model.
In regard to your comments on PUT:
This is a matter of opinion, but... for many developers it's completely acceptable to allow partial update via PUT. So you could update the resources without specifying everything; existing fields would remain unchanged. If you choose this behavior, it can complicate your (server-side) code when dealing with edge cases. For example, how does a client indicate that he wants to erase or delete a field? (Passing null may work, but for some data, null is a meaningful value.)
Why worry about PUT? If you want partial update, it's easy to use POST, with a verb (eg, "partialUpdate") in the query params. Actually this is what Roy Fielding advocates, and it makes sense to me.
A partial update would then be something like this:
POST /products/123456?action=partialUpdate
*headers*
{
"description" : "A fabulous paperweight designed in Sweden, now at a new low price." },
"price" : 1.78
}
I would use option 2, but instead of image_id, store the image URL. Also, don't be afraid to use custom scripts to return what you need (for example, displaying ALL products and images). REST is a design GOAL, not necessarily an implementation truth. Your design would still be RESTful.
I agree with the other 2 answers and I think that you should choose option number 2. But you also asked about getting a list of products, so here is my answer regarding it.
Think of using another resource that can be used with GET only, that resource will return a list of products. In this way there would be only one HTTP request for consuming the list. In case that there is a chance that the list can be very big, you would need to implement some kind of paging mechanism.
For example, lets say that you need to return 2500 products but you decided to return no more than 1000 products. The first GET request would return the first 1000 items and would also include in the answer the URL to consume the next "page", in this case the next 1000 products, then in the second request you would return products 1001-2000 with a URL to the next "page", in this case the last 500 products.
Then the consumer would be able to get the images as well if needed. You can use this list option for the images as well, but the bunch of images should be significantly smaller in each "page". I would not recommend of choosing the list mechanism to consume images.