How should I implement a COUNT verb in my RESTful web service?
Solution 1
The main purpose of rest is to define a set of resources that you interact with using well defined verbs. You must thus avoid to define your own verbs. The number of resources should be considered as a different resource, with its own uri that you can simply GET. For example:
GET resources?crit1=val1&crit2=val2
returns the list of resources and
GET resources/count?crit1=val1&crit2=val2
Another option is to use the conneg: e.g. Accept: text/uri-list
returns the resources list and Accept: text/plain
returns only the count
Solution 2
You can use HEAD without breaking the HTTP specification and you can indicate the count by using an HTTP Range header in the response:
HEAD /resource/?search=lorem
Response from the service, assuming that you return the first 20 results by default:
...
Content-Range: resources 0-20/12345
...
This way you transfer the amount of resources to the client within the header of the response message without the need to return a message body.
Update:
The solution suggested Yannick Loiseau will work fine. Just wanted to provide one other alternative approach which can be used to achieve what you need without the need to define a new resource of verb.
You can use GET and add the count into the body of the message. Then, if you API allows clients to request a range of results, you can use that in order to limit the size of message body to a minimum (since you only want the count). One way to do that would be to request an empty range (from 0 to 0), for example:
GET /resource/?search=lorem&range=0,0
The service could then respond as follows, indicating that there are 1234 matching resources in the result set:
<?xml version="1.0" encoding="UTF-8" ?>
<resources range="0-0/1234" />
Solution 3
Ignoring the HTTP specification and returning the object count in the response body of a HEAD request.
IMHO, this is a very bad idea. It may not work simply because you might have intermediaries that don't ignore the HTTP spec.
Defining a new HTTP method, COUNT, that returns the object count in the response body.
There is no problem with this approach. HTTP is extendable and you can define your own verbs. Some firewalls prohibit this, but they are usually also prohibit POST and DELETE and X-HTTP-Method-Override header is widely supported.
Another option, to add a query param to your url, something like: ?countOnly=true
claymation
Updated on June 03, 2022Comments
-
claymation almost 2 years
I've written a RESTful web service that supports the standard CRUD operations, and that can return a set of objects matching certain criteria (a SEARCH verb), but I'd like to add a higher-order COUNT verb, so clients can count the resources matching search criteria without having to fetch all of them.
A few options that occur to me:
Ignoring the HTTP specification and returning the object count in the response body of a HEAD request.
Duplicating the SEARCH verb's logic, but making a HEAD request instead of a GET request. The server then would encode the object count in a response header.
Defining a new HTTP method, COUNT, that returns the object count in the response body.
I'd prefer the API of the first approach, but I have to strike that option because it's non-compliant. The second approach seems most semantically correct, but the API isn't very convenient: clients will have to deal with response headers, when most of the time they want to be able to do something easy like
response.count
. So I'm leaning toward the third approach, but I'm concerned about the potential problems involved with defining a new HTTP method.What would you do?
-
Yannick Loiseau about 13 yearsthe Content-Range header represent the amount of the representation that is sent, in bytes. I don't think it's applicable here (w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16)
-
MicE about 13 yearsActually I think that it is, but I may be misunderstanding the RFC (correct if I am, please). The part of the RFC which you are referring to doesn't provide an example, but it refers you to another section which mentions other range units (w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.12). The RFC defines only
bytes
as units, however it does not forbid usage of other ranges. -
Yannick Loiseau about 13 yearsYour right that you can define other units (in this case resources), and then request by range, or use the response header to know the count. However, this means that only specific application can use this information, while using other resources any http client (browser, crawler, ...) can get the info.
-
claymation about 13 yearsI like the idea of exposing a separate resource for object count, but I don't know where to put it. Assume I have a dictionary resource, and it exposes words as keys (
GET dictionary/{word}
), then where would I put thecount
resource? If I didGET dictionary/count
, I could no longer have the word "count" in my collection. -
MicE about 13 yearsYes, that's right - it would be a custom defined unit, so only customized clients would understand it. But isn't that the same as when defining a new count resource? If you want http clients to actually understand it, you still need to customize them in some way (teaching them to use the count resource or the range header). In both cases, standard http clients will still have full access to resource data so we are not limiting them in that way. Still, I believe that using a new resource is the more standards-compliant way in this case (since we don't need to rely on custom defined units).
-
Yannick Loiseau about 13 yearsthe count resource doesn't have to be a subresource of your dictionary, as long as you provide a link to it, which you should do anyway since the hypermedia is the engine of your application
-
Yannick Loiseau about 13 yearsYou cant teach client to use (discover) it with hypermedia, which is impossible (or far harder) with a custom unit or header. However, I like this range approche to provide a more "semantic" interface to paginate results for example (with the more classical query params as fallback)
-
FishBasketGordo about 10 yearsAre there any guidelines about how to implement something like getting the count of items in a dictionary resource? You can't just do GET dictionary/count, as @claymation points out above, so what's a simple, clean way to do it?
-
James Billingham almost 10 yearsNo reason you couldn't use a custom header. E.g.
Content-Count
orResource-Count
.