Hacker News new | ask | show | jobs
by jashkenas 4923 days ago
One neat trick that I think is worth adding to the discussion: URL templates.

Returning URL templates as part of your API response can give you the benefits of having a clean way to access sub-resources, without the headaches and bloat of having to enumerate every possible desired sub-URL.

For example, in DocumentCloud, a document's canonical representation has a unique URL for the content of every page as plain text, and as an image, in several different rendered sizes. Instead of doing something silly like this:

    resources: {
      text: [
        "http://www.documentcloud.org/documents/1/pages/page-1.txt",
        "http://www.documentcloud.org/documents/1/pages/page-2.txt",
        "http://www.documentcloud.org/documents/1/pages/page-3.txt",
        ...
      ],
      largeImages: [
        "http://www.documentcloud.org/documents/1/images/page-1-large.png",
        ...
      ],
      thumbnailImages: [
        "http://www.documentcloud.org/documents/1/images/page-1-thumb.jpg",
        ...
      ]
    },
    ...
... where you might have 5,000 pages in a document, you can imagine how unacceptably large that response might become. Instead, a single URL template can do the work. (http://tools.ietf.org/html/rfc6570) The spec has a whole bunch of goodies in it, but we just need the most basic interpolation feature for this case (real example, you may have to scroll sideways to see the complete URL):

    "pages": 5058,
    "resources": {
      "page": {
        "image": "http://s3.documentcloud.org/documents/21939/pages/sotomayor-s-senate-questionnaire-p{page}-{size}.gif",
        "text": "http://www.documentcloud.org/documents/21939/pages/sotomayor-s-senate-questionnaire-p{page}.txt"
      },
      "pdf": "http://s3.documentcloud.org/documents/21939/sotomayor-s-senate-questionnaire.pdf",
      "published_url": "http://documents.nytimes.com/sotomayor-s-senate-questionnaire",
      "related_article": "http://www.nytimes.com/2009/06/05/us/politics/05court.html",
      "search": "http://www.documentcloud.org/documents/21939/search.json?q={query}",
      "text": "http://s3.documentcloud.org/documents/21939/sotomayor-s-senate-questionnaire.txt",
      "thumbnail": "http://s3.documentcloud.org/documents/21939/pages/sotomayor-s-senate-questionnaire-p1-thumbnail.gif"
    },
Basically, all of the simple URLs a Viewer might need to use in order to browse the document, search the text, and view related resources. In the past, when we've needed to change or expand the number of resources (adding HTTPs-only support, changing the URLs at which the page images are stored, or adding larger sizes of page images), it's been relatively easy to do, without breaking the viewers, or invaliding previously-valid JSON representations of the document. Here's the complete link to the above:

http://www.documentcloud.org/documents/21939-sotomayor-s-sen...

2 comments

> One neat trick that I think is worth adding to the discussion: URL templates.

100% agree - URL templates enable succinct discoverability. Moving link generation to the client reduces computation time on the server which no longer has to generate inline links as well as the payload size of the response.

The RFC6570 spec is great, has numerous implementations[1] and a through test suite[2]. I am also surprised that this is not a standard part of every hypermedia implementation.

[1] http://code.google.com/p/uri-templates/wiki/Implementations

[2] https://github.com/uri-templates/uritemplate-test

Just a nit, but the syntax for query arguments would be: "http://www.documentcloud.org/documents/21939/search.json{?q}"