Question

A straightforward question: if I am building a stateless client, which 'changes page' between requests, how do I properly consume a hypermedia API?

A key point of course is that the client should not construct URLs. If we were to for example fetch a collection of some kind (let's say fruits), each collection entry would feature a URL to link to the individual fruit resource in the API. Great.

[ { "name": "Apple", "url": ".../fruits/15" } ]

However in my client, after presenting a list of fruits, I wish to link the list through to a different front-end page with details for the fruit. Such a details page should of course be bookmark-able, etc. The precise structure of the front-end URL is I realise, philosophically, of little concern - but it is of practical interest to the question below.

<a href="?">Apple</a>

The question then is, upon loading a fruit details page, how does the client with no current context decide on the API URL to GET?

/my/frontend/stuff/fruits/{?}

Now what :o?

A solution which initially springs to mind is to have an 'item' URL template in the collection response, and to use the named parameter(s) therein to construct the page URL. The details page would then query the API to recover the same 'item' URL and implant the parameter(s) it was passed. This doesn't seem ideal, however it does achieve the desired decoupling.

Thanks in advance.

Was it helpful?

Solution

A web browser is the stateless client most familiar to many users. What you are asking for is known as URI templating and is supported by various hypermedia formats. For example, in HTML:

<form action="/api/fruits" method="GET">
  <input type="number" name="id" value="1" min="1">
  <button type="submit">Get Fruit</button>
<form>

will of course generate GET requests to the URI /api/fruits?id=1 when submitted.

Other hypermedia formats such as HAL allow templating anywhere in the URI, and are better suited to web applications than HTML. You need to look into the templating mechanisms supported by your preferred hypermedia representation format or switch to a format that supports what you need.

Of course, in HTML due to poor templating, we have to list every desired URI and paginate long lists:

<a href="/api/fruits/1/">Apple</a>
<a href="/api/fruits/2/">Banana</a>
<a href="/api/fruits/3/">Citrus</a>
...
<a href="/api/fruits/?page=2" rel="next">Page 2</a>

To be honest though, if users are going to directly input IDs, you should probably allow HTML and query string parameters too. It will help third-party client developers when they are building against your API, and it's availability will help if you ever need to debug with end users. Just point them to a URL and ask "Does it work if you go here?"

OTHER TIPS

If I understand the problem correctly, there are two steps in the workflow:

Step-1: Client – GET(/api/fruits/)

  • Returned: [{“name” : “Apple”, “Id” : 1 }, {…}]

Step-2: Client – GET(/api/fruits/1/), GET(/api/fruits/2/), …

  • Details of each fruit is returned

The client must already know the “root” URL- “/api/fruits/” in order to get the list in Step-1. For it to get the individual fruit details as in Step-2, the client concatenates the “root” URL - “/api/fruits/” and “Id” returned in Step-1.

Not sure if you are familiar with the popular javascript framework Backbonejs. Its model supports this out of the box. I believe that most other frameworks should support this type of workflow as well.

You can take a look at these backbone specific links as examples:

Hope it help

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top