.NET & Funky Fresh

Syndication

News

  • <script type="text/javascript" src="http://ws.amazon.com/widgets/q?ServiceVersion=20070822&amp;MarketPlace=US&amp;ID=V20070822/US/bluspiconinc-20/8001/8b68bf4b-6724-40e7-99a5-a6decf6d8648"> </script>
Alt.Tekpub REST

Mr. Conery has been working through building a RESTful API over on his blog. He’s tired of theory and has called on the community to submit some concrete examples in order to shed some light on the situation. I’m no expert in this area (I usually stick to UI stuff), but I have some experience, so I thought I’d make a contribution. Here’s some thoughts.

Issuing a GET to http://api.alttekpub.com returns:

<alttekpub>
  <links>
    <link rel="self" href="..." />
    <link rel="rels/productions" href="..." />
    <link rel="rels/new-episodes" href="..." />
    <link rel="rels/productions-by-category" href="...?category={category_name}" />
  </links>
  <categories>
    <category name="Microsoft" />
    <category name="Ruby" />
    <category name="JavaScript" />
    <category name="Mobile" />
  </categories>
</alttekpub>

One of my goals here is that clients only need to know a single uri: http://api.alttekpub.com After that, they should be able to follow links inside the document in order to navigate all the data and exercise all the features of the API. Above, you can see that the alttekpub api exposes links to several other documents: productions, new episodes and productions by category. These are identified by a rel attribute which is used to specify the link’s relationship to the enclosing document. Every document has a link that points to itself at a minimum. The last link in this example is parameterized. The api provides the various options for parameters in its document below. Here’s an alternative way you could represent the same concept, by borrowing some ideas from html:

<alttekpub>
  <links>
    <link rel="self" href="..." />
    <link rel="rels/productions" href="..." />
    <link rel="rels/new-episodes" href="..." />
  </links>
  <form method="GET" action="...">
    <select name="category">
      <option value="Microsoft">Microsoft</option>
      <option value="Ruby">Ruby</option>
      <option value="Javascript">Javascript</option>
      <option value="Mobile">Mobile</option>
    </select>
  </form>
</alttekpub>

I actually like this a little better, but I’ve seen both ideas used here and there. What is neat is that the api is self-documenting and there’s no need for the client to know how to construct uris. Everything is provided by the server. Let’s ay we follow the link for rels/productions. Here’s what we might get back:

<productions>
  <links>
    <link rel="self" href="..." />
    <link rel="next" href="..." />
  </links>
  <production>
    <name>RavenDB</name>
    <author>Oren Eini</author>
    <links>
      <link rel="self" href="..." />
      <link rel="rels/episodes" href="..." />
    </links>
  </production>
  <production>
    <name>Art of Speaking</name>
    <author>Scott Hanselman</author>
    <links>
      <link rel="self" href="..." />
      <link rel="rels/episodes" href="..." />
    </links>
  </production>
  <!--other productions elided-->
</productions>

It’s just a simple list of productions. But, there’s a couple of things to note. First, notice the rel=”next” If there are a lot of productions, the server may choose to paginate them. If that is the case, and there’s a second page, we will have a link with rel=”next” as above. We can handle paging backwards in a similar fashion. In fact, there’s a host of standard rels which you can and should leverage when it make sense. You can find them here: http://www.iana.org/assignments/link-relations/link-relations.xml  Another thing to note, is that we’ve represented the collection of episodes in a production with another link. Following the RavenDB production’s rels/episodes link yields:

<episodes>
  <links>
    <link rel="self" href="..." />
  </links>
  <episode>
    <links>
      <link rel="self" href="" />
    </links>
    <name>Why You Should Care About RavenDB</name>
    <description>We've all heard of NoSQL...</description>
    <videos>
      <video type="video/mp4" href="..." />
      <video type="video/ogg" href="..." />
    </videos>
  </episode>
  <episode>
    <links>
      <link rel="self" href="" />
    </links>
    <name>Understanding Document Names</name>
    <description>In this short episode we explain how documents are named with RavenDB - and why.</description>
    <videos>
      <video type="video/mp4" href="..." />
      <video type="video/ogg" href="..." />
    </videos>
  </episode>
</episodes>

There’s not really anything new here. We just have basic xml with links. In the above examples, I’ve only shown a “readonly” api for a custom vendor-specific format. But, these concepts can all be expanded on to model all sorts of things through links, forms, etc. Here’s a couple of ideas you can implement to improve things further:

  1. Use JSON instead of XML :)
  2. Add a “title” attribute to your links. This can be used by clients to display the UI. For example, a client might scan the links in a resource and generate a series of buttons or a toolbar for each link. It could use the title attribute to populate the button’s text. Clicking the button would just activate the link. It’s very similar to the way a browser’s <a /> tag works, and if the client is coded in this way, it allows a lot of flexibility for the service author. They can evolve and extend their service with less changes needed by api consumers.
  3. Embed resources. After recording usage data, you might discover that a request for productions is quickly followed by a request for episodes. Perhaps you can improve the api usage experience by embedding the episodes in the production documents, so only a single request is needed? There are multiple ways you can design your format to handle this situation. But you might want to consider using something that’s already been designed for this scenario, such as HAL.

The takeaway here is that a key concept in REST is hypermedia controls, which I’ve represented mostly with links (and a form). These allow the API to document itself, alleviating the need for the client to be coded with specific knowledge of link construction. It also allows the service to evolve more easily by adding additional controls over time or by completely changing uri’s or even whether or not certain related documents are embedded.

Oh..and just a reminder that I’m not a REST expert. But hopefully this example sheds some light, however dim :)


Posted 03-05-2012 1:43 AM by Rob Eisenberg
Filed under: ,

[Advertisement]

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)