6

Let's say I have REST API which provides me list of something and I want to implement paging support - possibility to tell "give me records 20-29 (page 3)". Currently, I don't care about implementation server-side, but about how client tell API he want specific page.

You can pass it in URI (/some-list?page=3) or send it via POST data (you can't use it with GET), but what about headers? Is it good practice (or against something)?

Can I use range or some custom X- header to define, which page (or offset and length) I want to receive?

//EDIT: I also don't care about SEO, search engines etc. My use case is API used internaly in my code.

Pavel Štěrba
  • 319
  • 1
  • 3
  • 8
  • 1
    This would be a bit uncommon. The `range` is more for data requests like getting part of a video file (e.g. when you click the progress bar in a youtube video). To start with in most cases it will be just more complicated (at least require javascript) to get this working. Also it would make it more or less impossible for search engines to follow you links, so you would possibly have negative SEO effects if that is relevant to your site. – thorsten müller Jul 08 '15 at 08:13
  • I edit original post to better explain my use case. I don't case about SEO, I want to use this API as backend webservice, which will provide data to my code. – Pavel Štěrba Jul 08 '15 at 08:44
  • 1
    This still is more complicated and not the standard. I just fail to see why you would want to do that at all? There seems to be no real advantage to it, only makes using your API more complicated. As it is now you will have libraries that can easily make GET requests (also you can easily use command line tools like wget or curl for testing your API) and all you need to do is concatenating a simple string into the correct URI with all params. All this without worrying about how to get your tools to change header info. It's simple, it works, so you should have a very good reason to change it. – thorsten müller Jul 08 '15 at 08:49
  • If you rally like headers you can use them in response to pass number of items and current offset – aiven Jul 04 '21 at 21:02

2 Answers2

4

There are several possible negatives when considering custom header fields.

  1. Browser based testing will be difficult
  2. Proxies sometimes remove/mangle headers fields
  3. It breaks HTTP cacheing
  4. Other developers will not expect it

When returning a dynamic list, you will want cacheing disabled, so that shouldn't be a problem.

If you never expect to use a browser to test your endpoints, you know all the proxies which will be used, and you feel you can document the behavior so future developers won't be surprised by this novel behavior, then try it out.

I've had similar ideas before for HTTP header fields, but they've never worked out. You might have better luck.

Jeffery Thomas
  • 2,115
  • 1
  • 14
  • 19
  • Thanks for answer. Well, my plan is to use it in local network without proxies, firewalls etc. Also, there will be client for API, and it will manage that all headers will be set properly. Also, I'm thinking about `range` more than custom one, because proxies SHOULD eventualy keep this standard header presented... Did you face some specific problems that you want to share? The more, the better. – Pavel Štěrba Jul 08 '15 at 11:19
3

For pagination, you should be considering the techniques described in RFC 5005. Roughly, each page of results is a separate resource, which itself contains hyperlinks to the previous/next page of results. Then, as usual, the application can just follow the links to navigate from one application state to the next.

The actual spelling of the uri doesn't matter too much. You could treat the ranges as part of the query parameters, or as separate resources under a pages collection, or...

/some-list?page=3
/some-list/3
/some-list/pages/3
/some-list/records/20?order=ascending&limit=10

You'll want to give some thought to whether page 3 "now" has the same representation as page 3 at some other time. If not, you may want to have these resources redirect to another identifier that has a better caching lifetime.

Some apis will identify paging resources by putting the pagination data in the path; which isn't a great fit if you believe that the path should represent the position of a resource in a hierarchy. Query parameters are a much better fit.

As what you are doing is a safe query (no changes to server state), GET, rather than POST, is certainly the correct method to be considering.

Even if you need to allow the client to specify the query parameters (as opposed to defining the pagination links within the hypermedia), you should still be treating this as a simple GET. The heuristic to justify this choice is the behavior of a web browser, which packs parameters into the query string when a form with the get action is submitted. It works, it's stateless, the browser is still following a link contained within the application state.

If you aren't describing the application state with an html representation, then UriTemplates are a reasonable approach to representing the link. You could document the contraints on the parameters are part of the definition of the link relation.

VoiceOfUnreason
  • 32,131
  • 2
  • 42
  • 79