Note that there are some explanatory texts on larger screens.

plurals
  1. POWell-behaving RESTful Client Interactions
    primarykey
    data
    text
    <p>I have what seems to be a fairly simple question about implementing a data access client that strictly adheres to REST architectural principles. To start, let's assume I have a well-behaving REST API that I want to consume using a Django application. I'll start by discovering what services are available <strong><em>(edited for follow-up)</em></strong>:</p> <pre><code>GET example.com/services/ HTTP/1.1 HTTP/1.1 200 OK &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;services&gt; &lt;service&gt; &lt;name&gt;Widgets&lt;/name&gt; &lt;link&gt;http://example.com/services/widgets/&lt;/link&gt; &lt;item_link&gt;http://example.com/services/widgets/{widget_id}/&lt;/item_link&gt; &lt;/service&gt; &lt;service&gt; &lt;name&gt;Factories&lt;/name&gt; &lt;link&gt;http://example.com/services/factories/&lt;/link&gt; &lt;item_link&gt;http://example.com/services/factories/{factory_id}/&lt;/item_link&gt; &lt;/service&gt; ... &lt;/services&gt; </code></pre> <p>Now, since I'm building a Django application based around consuming this API, how would I continue to keep exploring these services RESTfully? To adhere to REST principles, my application must be driven by the hypermedia received. I suppose the first step is easy enough -- interacting with a service by the name given. I set up a Django view as follows:</p> <pre><code>def get_service(request, service_name): doc = etree.parse(urllib.urlopen('http://example.com/services/')) uri = doc.xpath("service/name[.='%s']/following-sibling::*" % service_name)[0].text ... </code></pre> <p>From which I'll perform another request <strong><em>(edited for follow-up)</em></strong>:</p> <pre><code>GET example.com/services/widgets/ HTTP/1.1 HTTP/1.1 200 OK &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;widgets&gt; &lt;item_link&gt;http://example.com/services/widgets/{widget_id}/&lt;/item_link&gt; &lt;widget&gt; &lt;id&gt;1&lt;/id&gt; &lt;name&gt;Whizbang Foobar&lt;/name&gt; &lt;link&gt;http://example.com/services/widgets/1&lt;/link&gt; &lt;/widget&gt; ... &lt;/widgets&gt; </code></pre> <p>Now I'll display a simple list of widgets in a rendered Django template. From here though, how do I continue to interact with this service RESTfully? Perhaps I've befuddled myself into confusion, but the only <em>reasonable</em> things I can come up with are implementing a numerous amount of application views or a thin Django data model to persist the service URI. </p> <p>My main concern boils down to that this is trivial to do without strictly adhering to REST architectural guidelines, but I feel like I've missed the boat completely in trying to do so. I understand designing proper REST APIs and clients isn't "easy", but it seems that I'm in dire need of a similar example to work through the actual implementation.</p> <p>I apologize for the length and verbosity of the question and the inevitable facepalming of wizened readers.</p> <p><strong><em>Follow-up:</em></strong></p> <p>Is the following a valid way (using URI templates) of implementing these interactions? For demonstration purposes (in lieu of a more abstract implementation), another Django view to retrieve a resource collection item:</p> <pre><code>def get_item(request, service_name, item_id): doc = etree.parse(urllib.urlopen('http://example.com/services/')) uri = doc.xpath("service/name[.='%s']/following-sibling::item_link" % service_name)[0].text ... </code></pre> <p>Then the subsequent request:</p> <pre><code>GET example.com/services/widgets/1 HTTP/1.1 HTTP/1.1 200 OK &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;widget&gt; &lt;id&gt;1&lt;/id&gt; &lt;name&gt;Whizbang Foobar&lt;/name&gt; &lt;tags&gt;foo bar baz ham eggs&lt;/tags&gt; &lt;index_link&gt;http://example.com/services/widgets/&lt;/index_link&gt; &lt;/widget&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload