Recently, I have been doing some extensive research on this and other issues related to the REST search call, and thought it was constructive to add some of my findings here. I am expanding the question a bit to include thoughts on paging, as well as counting, as they are related to each other.
Headings
Swap metadata is included in the response as response headers. The big advantage of this approach is that the response payload itself is just a request that requested the actual data request. Easier response handling for customers who are not interested in paging information.
There are many (standard and customizable) headers used in the wild to return information related to the paging call, including the total.
X-total-count
X-Total-Count: 234
This is used in some API that I found in the wild. There are also NPM packages to add support for this header, for example. Loopback Some articles also recommend setting this heading.
It is often used in conjunction with the Link header, which is a pretty good search call solution but does not contain general account information.
Link
Link: </TheBook/chapter2>; rel="previous"; title*=UTF-8'de'letztes%20Kapitel, </TheBook/chapter4>; rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel
I believe that by reading a lot on this topic, the general consensus is to use the Link header to provide paging links to clients using rel=next , rel=previous , etc. The problem is that he lacks information about the number of shared records, so many APIs combine this with the X-Total-Count header.
Alternatively, some APIs, such as JsonApi , use the Link format, but add the information in the response envelope instead of the header. This simplifies access to metadata (and creates a place to add general information about the account) by increasing the complexity of access to actual data (by adding an envelope).
Content range
Content-Range: items 0-49/234
Promotion of a blog article called Range heading, I choose you (for pagination)! . The author makes a big argument for using Range and Content-Range headers for pagination. When we carefully read the RFCs in these headers, we find that expanding their values outside the byte ranges was actually expected by the RFCs and is explicitly allowed. When used in the context of items instead of bytes Range header actually gives us a way to both request a specific range of elements and indicate to which range of the final result the response elements belong. This heading also provides a great way to show the total. And this is a true standard that basically displays one-to-one paging. It is also used in the wild .
The envelope
Many APIs, including those from our favorite Q&A website, use an envelope, a wrapper around the data, which are used to add meta-information about the data. In addition, OData and JsonApi standards use a response envelope.
The big drawback of this (imho) is that processing the response data becomes more complicated, since the actual data needs to be found somewhere in the envelope. There are also many different formats for this envelope, and you should use the correct one. This suggests that the response responses from OData and JsonApi are very different from each other, mixing OData in metadata at several points in the response.
Single endpoint
I think this has been covered quite fully in other answers. I did not investigate this because I agree with the comments that this is confusing since you now have several types of endpoints. I think it is beautiful if each endpoint is a (set) of resources (s).
Further thoughts
We not only need to provide search call meta-information related to the response, but also allow the client to request specific pages / ranges. It is also interesting to look at this aspect in order to get an agreed solution. Headers can also be used here (the Range header seems very appropriate) or other mechanisms such as query parameters. Some people advocate processing pages of results as separate resources, which may make sense in some use cases (e.g. /books/231/pages/52 ). In the end, I chose a wild range of commonly used query parameters, such as pagesize , page[size] and limit etc, in addition to supporting the Range header (and as a query parameter as well).