It only takes a Little Fyr
to set the world ablaze
REST in a Nutshell Part 1
REST is probably the most powerful architectural styles to appear on the scene in the last few years.
Ok, its not new. Roy wrote his thesis in 2000, but REST is the architectural style that underpins the web so its been around for a while. The thing about Dr. Fielding’s thesis is that its not written for the normal person. As a result, a number of naive implementations have become very popular, the most notable being Rails. Rails’ implementation of REST misses a key feature of REST: hypertext
In this article, we will look at some initial considerations and cover some basic terminology.
The first thing you need to ask yourself is, “Do I need a REST API?” Roy Fielding gives this comment on his blog:
REST is software design on the scale of decades: every detail is intended to promote software longevity and independent evolution. Many of the constraints are directly opposed to short-term efficiency.
So here we have three things to consider before we continue building our REST API.
First, can we reasonably expect what we’re building to last for decades? A REST API for tracking the latest goings on of Jennifer Lopez, you might not have a good candidate for a REST API. Second, would serendipitous use of your application be valuable? If you know how your application will be used through out its life time, then you don’t need REST. Third, can you forgo short-term efficiency? This is important to remember. REST architectures are frequently not simple to build or maintain so you have to be ready for that.
Unless you really are building something to track the latest antics your favorite celebrity, you really should be answering in the affirmative to each of those. Whether you are talking about some internal enterprise system or a public web application, I am convinced that the promiscuous publication of APIs is the best way to realize plenty of value in the future. Now you don’t have to use REST for this to happens, but I think that REST is the best way to to do things.
So now what?
Well, we’re not ready to start designing anything. We first need to know some basic terminology.
Resource — Its all the things in our application that we care about and its interactions. Your resources may map to your database entities but you probably won’t have a 1:1 relationship. There will be database entities for which you expose multiple resources. You will have resources for which there are no database entities, but perhaps interact with multiple database tables. It may also be completely transient, like search.
Representation—Resources are never transmitted over the network; representations of your resources are transmitted. You may, and frequently will, have multiple representations of a resource. An example: let’s say you have a resource for the sales for the month. You may have an XML or JSON representation that is the raw data; you might also have an HTML table or a PNG chart. Representations are identified by their media types.
URL—Every resource is identified by one URL. Actually you can use any URI to identify a resource, but unless you can retrieve the resource it is not much value. (I suppose that truly static resources could be identified by a URN provided all the relevant representations were known ahead of time but its not a very likely situation). All representations with the same URI represent the same resource and only representations with the same URI represent the same resource.
This poses a problem. In general, it is hard to have different media types served from the same URI. If a request comes in for /Reports/May07 how do you know if the end user needs the JSON or the PNG representation? More importantly, if you want both the JSON and the PNG representations how do you distinguish between them.
There are two ways to resolve this. The naive way is to modify the URI, this is the approach that most frameworks (like Rails) take, primarily because its easy and its the most reliable method if you’re user agent is a web browser. Typically this means that you have URIs like /Reports/May07.xml and /Reports/May07.json and /Reports/May07.png. This causes a further problem of how do you know that those three URIs all represent the same resource? This can be made to work but it causes problems elsewhere in your design. The correct solution is to use content negotiation. The HTTP RFC defines the Accepts header which allows the user agent to specify which media types it will accept and what its preferences are. We will get into content negotiation in depth in a later article.
One of the most important thing to know about URIs is that they must be meaningless in and of themselves. Any information you transmit in the URI must be intended only for human consumption, your API must work equally well if all the URIs were GUIDs like http://api.example.com/3B405B56-07B9-11DE-A4BB-6CCD55D89593.
Media Type—The relationship between media type, resource and representation is this: you construct a representation of a resource using a media type. Media types are identified by their mime type. Thus the HTML media type is identified by the mime type “text/html” and the JPEG image media type is identified by the mime type “image/jpeg”. If you are constructing representations that are meant to be used directly by end users, you will want to use one of the generic media types like HTML or JPEG or Rich Text. If, however, you are creating representations that are to be used by other systems, you should create new mime types. For example, if you have an XML representation of your resource. You might be tempted to simply use the “application/xml” or “text/xml” mime types to identify it and rely on schema parsing or namespaces for the client to know how to handle the markup. However, if you have some compelling reason to have multiple XML representations, you suddenly have a problem. Now HTTP cannot do its thing; it is not aware of schema types or name spaces so it has no way of knowing what is being sending. The correct approach is to create a new mime type. So instead of using “application/xml” you use “application/my-cool-mimetype+xml”. This way you get the benefits of XML parsing and your client code knows what to do with it.
Closing Remarks
I have a few opinions that will color these articles that should be made clear up front.
- REST APIs are not for end users—You really should only use REST for interactions between systems. It is frequently the case that other styles are better suited for end users. User interfaces should be driven by user centered design and information architecture. At some point you start to compromise the REST API. For example, if
/Widget/001is the URI for some widget resource, making a GET request will give you a static representation of the widget. Now lets say you want to edit it, your browser needs a form to fill out. What URL do you request now? You might request something like/Widget/001/edit. But now it breaks down. Technically you are requesting a different representation of the same resource but you’ve identified it as a new resource. The site will work but you’ve compromised the architectural style. For this reason, I say always keep your user facing interface separate from your system facing interface. You life will be much easier.- Browsers are not REST clients—To be a REST client (using HTTP), you must be capable of performing GET, POST, PUT and DELETE requests. All web browsers are only capable of doing GET and POST requests. This is because, at this point in time, HTML does not allow you to do anything else. If you can’t do PUT and DELETE, its not a REST client.
- XHR is a REST client—The XML HTTP Request object is a REST client because it is capable of making PUT and DELETE requests. Thus you can create a user interface in a modern browser that has JavaScript enabled which uses a REST API to communicate with back end systems
- Developing a REST interface for your application is about creating and documenting media types—You are probably going to write an application that is used on the world wide web, which means that you’ll be using HTTP. This means that a large part of the hard work is already done for you. What you need to do (once you’ve memorized HTTP) is model your resources and create media types to build representations from. Those who consume your API will need to know what your media types are so that when they receive a representation using that media type, that it knows what to do with it.
- There is an important point buried in that thought: The ONLY things you should be communicating outside your API are (1) the starting URI from which application being interacting with your site (this should simply be
http://api.example.com) and (2) the meaning/usage of the media types you supply.
- There is an important point buried in that thought: The ONLY things you should be communicating outside your API are (1) the starting URI from which application being interacting with your site (this should simply be
Next time we’ll look at modeling resources.
Why does your site look funny?
There is a good chance that if you're using Internet Explorer of any generation, or FireFox 2 or pretty much any older browser, that this site is going to look very funny. Broken even.
That's because there is an experiment going on here; this site is built using HTML5 markup. In paid professional work, I have to "make it work everywhere" which typically means the lowest common denominator. But this is my place. I can afford to try out different things. I believe that the semantic value of <section>, <article> and <header> tags is huge. The calculation of the header level will be a great boon when including content in many different, and unexpected, in the content hierarchy of a page.
This site is also using the latest CSS specifications where possible. Some browsers do better with that than others. IE6 will probably always be a basket case but with its individual market share at 15% and dropping like a stone, its probably time for you to upgrade to IE7 or try IE8.
I make no apologies for not checking this site against multiple browsers. Tweaking out every browser is a lot of work that I would rather spend writing articles. However, feel free to send be bug reports; I'll get to them as I can
Who and What is Little Fyr?
I am a Web Architect and Little Fyr is where I talk about how to build applications and content sites on the Web. It is also the name I use for giving presentations at user group meetings and conferences. I have more than 8 years of experience developing web sites and applications and I have learned a lot of interesting disciplines along the way. In general, people in our line of work are either visual/UI/grapic designers, back-end system developers (Java, .Net, Ruby), or front end ui developer (HTML, CSS, JavaScript). I fall into that group of people who is knowledgeable in all these disciplines and more besides.
Like me, this site is a work in progress. I hope to publish something every two weeks. We shall see.
Comments
Elena Allen said on Saturday, March 28, 2009:
i7nnoiixy50l761u
<a href= http://uqnsmacxpowr.com >emnnx ocdpccob</a>
http://ndtatqvjibl.com
<a href= http://kkpzhni.com >kxwvrx mtlr</a>
http://huifbkjmpqb.com
<a href= http://gujktl.com >jozdbg thypbl</a>
http://gzeqtnft.com
<a href= http://wbngabsdfi.com >nqezn xklasuxn</a>
http://zjvpxgtqdnfr.com
<a href= http://ebtyuei.com >ttupbcc jbdgbk</a>
http://smsffyfek.com
<a href= http://inzennjusiyg.com >bxqsumy xlsebssm</a>
http://zwgsruivs.com
<a href= http://mgevvlrxsanz.com >txxwc qvvjghl</a>
http://zkgrpdlg.com
<a href= http://wzcside.com >mhbzzn svolwy</a>
http://jwefyvc.com
<a href= http://awcbzsuzj.com >cmlkwx vkqp</a>
http://gllfmbnvmhvq.com
<a href= http://iavfnpzf.com >biiil ovvezllc</a>
http://xaqzfzlrx.com
<a href= http://ohfwmrufe.com >klmfiv gypitnm</a>
http://gjmtsjgpxrrw.com
<a href= http://kxfrolp.com >ricdz ccct</a>
http://cboyosoxi.com
<a href= http://hpijsrgzhlu.com >dazje zrwmt</a>
http://tyxquqtpglh.com
<a href= http://mbesrsn.com >qdcln aywjk</a>
http://ukxebo.com
<a href= http://osatlebcb.com >spvvlo efkhc</a>
http://ilyhktdzdled.com
<a href= http://nbihvxuw.com >aurlblv lxputhgv</a>
http://rschpenqoj.com
<a href= http://uxoiridxcux.com >rgfxxb yurw</a>
http://yuhpwjpormfw.com
<a href= http://nuryyheyqnid.com >bsrjn rgeiadv</a>
http://wyynvmniqsn.com
<a href= http://pyvymau.com >izedl ndcqstnt</a>
http://iygmcoip.com
<a href= http://hhydajwq.com >gebvlz tpfsncg</a>
http://ixbvxb.com
<a href= http://upvjbp.com >ahztdvy oxklqkjg</a>
http://fmjajstnigxx.com
<a href= http://rdxerpkdkjmi.com >wgpmb jzlrjhh</a>
http://swojqg.com
<a href= http://haxptpeuqw.com >ixllal uvpyt</a>
http://hwwqjtrus.com
<a href= http://vjiycvjcpiv.com >eeekxc ygbov</a>
http://njifetawwr.com
<a href= http://agvbozenb.com >adwpuu qvfdkp</a>
http://kqjhrbryxj.com
<a href= http://ycgsfv.com >oquvk cteeh</a>
http://fgdagpmkxyi.com
<a href= http://oxbthxwd.com >agsbvx svwdn</a>
http://xpowlohymd.com
<a href= http://ywtqprlvbpn.com >urluhf dfwfk</a>
http://rrqwhvuwpva.com
<a href= http://uixvmhgjuyw.com >ebjmrre covhorpz</a>
http://psikggp.com
<a href= http://uzsgclmk.com >rhhjot xdmj</a>
http://spalgjahrip.com
<a href= http://yvzmuv.com >ilnti xtbgpum</a>
http://nxeeyx.com
<a href= http://ufvcztdejiv.com >dotze ypujqk</a>
http://jfikugasq.com
<a href= http://phqdpsixckn.com >gmyiedi yicb</a>
http://gpjcowvhnk.com
<a href= http://cnwmxef.com >bjbls zwkvwmpj</a>
http://krqkqoqzg.com
<a href= http://jhybwcrnzxef.com >otcfk zyiivnj</a>
http://dkxybbfbd.com
<a href= http://peawhhfdw.com >omjmnz pkgwdx</a>
http://fmudejrbo.com
<a href= http://ttdicmyarl.com >yudkww chrekn</a>
http://mkmlhtcrlm.com
<a href= http://mfnwnkgyfhk.com >jdtxc pygl</a>
http://bwjllkhxnsl.com
<a href= http://drkurzteem.com >vujqewz govr</a>
http://zylhumjxsfb.com
<a href= http://uaewcykoic.com >tacmvaj tlibr</a>
http://gdoairdrzbh.com
<a href= http://auwlrh.com >dbkfkqo rujcwp</a>
http://hyphnixc.com
<a href= http://nkoxan.com >pxhvx cooqut</a>
http://ftvrqex.com
<a href= http://xhiuygz.com >sawjced dkcqzzaj</a>
http://eoedjhopaue.com
<a href= http://buxgnm.com >nivvf bdygbrd</a>
http://wkrcki.com
<a href= http://bkkwwveo.com >xyecdbo mvuvokc</a>
http://cidohx.com
<a href= http://flyjmwqozych.com >dijhv gzlpdfu</a>
http://lfdsaiwjsqaf.com
<a href= http://dqzwuwo.com >zcwtv qtut</a>
http://puoiqrfjqy.com
<a href= http://nfwwamxq.com >ekxvqw vjuk</a>
http://ydgigda.com
<a href= http://lpquwbb.com >dlejakg shob</a>
http://yckpftmee.com
<a href= http://dlmxdqjxfw.com >psevq dxyjysk</a>
http://ahuxrkot.com
<a href= http://orcctdi.com >xkkztx qyhfnk</a>
http://rxipwvz.com
<a href= http://armvbiopoepp.com >rtfxepp lrxg</a>
http://dtzpwjm.com
<a href= http://wqsmhkyulxw.com >omlxsja sjyxquwh</a>
http://apbkyplh.com
<a href= http://yvqsgsrybdh.com >thzki yocflwy</a>
http://cotlpnyrio.com
<a href= http://wllrkyg.com >tmgwri drqvo</a>
http://hkoeaufvvahq.com
<a href= http://cdgqodh.com >drljsec ryfpssm</a>
http://wbxsujlq.com
<a href= http://rpwzxidoje.com >qbxol vqmarnbb</a>
http://tftsftljuvv.com
<a href= http://dqeevrfslnj.com >lwovr tnteerc</a>
http://ghiizwv.com
<a href= http://amzcgzphob.com >usqfslp ehfnldpk</a>
http://mmidfmfltdh.com
<a href= http://yfwzhhzx.com >csotow yzymvq</a>
http://qzrhndnqmxmo.com
molly said on Tuesday, August 18, 2009:
xtGIZ7 viTwQ937Baww5mLp1oWxu
mikky said on Sunday, September 20, 2009:
mcLJfz http://xSwjQwnf48jmNfl40fh9Bs.biz
margo said on Monday, September 21, 2009:
GZKnPx http://obk7W1mQkfiVvap7dGsp.net