Skip to content


Subversion checkout URL

You can clone with
Download ZIP
100644 252 lines (201 sloc) 10.7 KB
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
1 ---
2 published: true
3 title: Some People Understand REST and HTTP
4 layout: post
5 ---
7 This is a follow-up post to my post [here][1]. You probably want to
8 read that first.
27d2888 @steveklabnik No seriously, REST is over.
10 UPDATE: Please note that '[REST is over'](/posts/2012-02-23-rest-is-over).
11 'Hypermedia API' is the proper term now.
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
13 ## A few words on standards versus pragmatism
15 When I wrote my first post on this topic, I tried to take a stance that
16 would be somewhat soft, yet forceful. Engineering is the art of making
17 the proper trade-offs, and there are times when following specifications
18 is simply not the correct decision. With that said, my motivation for
19 both of these posts is to eradicate some of the ignorance that some
20 developers have about certain areas of the HTTP spec and Fielding's REST
21 paper. If you understand the correct way, yet choose to do something
22 else for an informed reason, that's absolutely, 100% okay. There's no
23 use throwing out the baby with the bathwater. But ignorance is never a
24 good thing, and most developers are ignorant when it comes to the
25 details of REST.
27 Secondly, while I think that REST is the best way to develop APIs, there
28 are other valid architectural patterns, too. Yet calling non-REST APIs
29 'RESTful' continues to confuse developers as to what "RESTful" means.
30 I'm not sure what exactly we should call "RESTish" APIs (hey, there we
31 go, hmmm...) but I'm also not under the illusion that I personally will
32 be able to make a huge dent in this. Hopefully you, humble reader, will
33 remember this when dealing with APIs in the future, and I'll have made a
34 tiny dent, though.
36 ## So who _does_ understand REST?
38 As it turns out, there are two companies that you've probably heard of
19c7f34 @steveklabnik Twillio -> Twilio
39 who have APIs that are much more RESTful than many others: [Twilio][2]
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
40 and [GitHub][3]. Let's take a look at GitHub first.
42 ### GitHub: logically awesome
44 GitHub's developer resources are not only beautiful, but thorough. In
45 addition, they make use of lots more of REST.
47 #### The good
49 GitHub uses [custom MIME][4] types for all of their responses. They're
50 using the vendor extensions that I talked about in my post, too. For
51 example:
53 application/vnd.github-issue.text+json
55 Super cool.
57 Their [authentication][5] works in three ways: HTTP Basic, OAuth via an
58 Authentication Header, or via a parameter. This allows for a maximum
59 amount of compatibility across user agents, and gives the user some
60 amount of choice.
62 Their [Pagination][6] uses a header I didn't discuss in part I: the Link
63 header. [Here]('s a link to the
64 reference. Basically, Link headers enable HATEOAS for media types which
65 aren't hypertext. This is important, especially regarding JSON, since
66 JSON isn't hypermedia. More on this at the end of the post. Anyway, so
67 pagination on GitHub:
69 $ curl -I ""
70 HTTP/1.1 200 OK
71 Server: nginx/1.0.4
72 Date: Sun, 07 Aug 2011 16:34:48 GMT
73 Content-Type: application/json
74 Connection: keep-alive
75 Status: 200 OK
76 X-RateLimit-Limit: 5000
77 X-RateLimit-Remaining: 4994
78 Link: <>; rel="next", <>; rel="last"
79 Content-Length: 29841
81 The Link header there shows you how to get to the next page of results.
82 You don't need to know how to construct the URL, you just have to parse
83 the header and follow it. This, for example, is a great way to connect a
84 resource that's not text-based, such as a PNG, to other resources.
86 #### The bad
88 There's really only one place that GitHub doesn't knock it out of the
89 park with their new API, and that's HATEOAS. GitHub's API isn't
90 discoverable, because there's no information at the root:
92 $ curl -I
93 HTTP/1.1 302 Found
94 Server: nginx/1.0.4
95 Date: Sun, 07 Aug 2011 16:44:02 GMT
96 Content-Type: text/html;charset=utf-8
97 Connection: keep-alive
98 Status: 302 Found
99 X-RateLimit-Limit: 5000
100 Location:
101 X-RateLimit-Remaining: 4993
102 Content-Length: 0
104 Well, at least, this is how they present it. If you ask for JSON:
106 $ curl -I -H "Accept: application/json"
107 HTTP/1.1 204 No Content
108 Server: nginx/1.0.4
109 Date: Sun, 07 Aug 2011 16:45:32 GMT
110 Connection: keep-alive
111 Status: 204 No Content
112 X-RateLimit-Limit: 5000
113 X-RateLimit-Remaining: 4991
114 Link: <users/{user}>; rel="user", <repos/{user}/{repo}>; rel="repo", <gists>; rel="gists"
116 You do get Links, but you have to construct things yourself. As a user,
117 you get the same thing. It doesn't change the links to point to your
118 repos, it doesn't give you links to anything else that you can do with
119 the API.
121 Instead, the root should give you a link to the particular resources
122 that you can actually view. Maybe something like this:
9274dd7 @locks small typo that borked the formatting of the code snippet
locks authored
124 $ curl -I -H "Accept: application/json" -u "username:password"
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
125 HTTP/1.1 204 No Content
126 Server: nginx/1.0.4
127 Date: Sun, 07 Aug 2011 16:45:32 GMT
128 Connection: keep-alive
129 Status: 204 No Content
130 X-RateLimit-Limit: 5000
131 X-RateLimit-Remaining: 4991
132 Link: </gists/public>; rel="public_gists", </user/repos>; rel="repos", <gists>; rel="gists"
134 And a bunch more, for all of the other resources that are available.
135 This would make the API truly discoverable, and you wouldn't be forced
136 to read their gorgeous documentation. :)
19c7f34 @steveklabnik Twillio -> Twilio
138 ### Twilio
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
19c7f34 @steveklabnik Twillio -> Twilio
140 I've always really enjoyed Twilio. Their API is incredibly simple to
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
141 use. I once hooked up a little "Text me when someone orders something
142 from my site" script, and it took me about fifteen minutes. Good stuff.
144 #### The good
19c7f34 @steveklabnik Twillio -> Twilio
146 Twilio has got the HATEOAS thing down. Check it out, their home page
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
147 says that the base URL is "". Without
148 looking at any of the rest of their docs, (I glanced at a page or two,
149 but I didn't really read them fully yet), I did this:
151 $ curl
152 <?xml version="1.0"?>
153 <TwilioResponse>
154 <Version>
155 <Name>2010-04-01</Name>
156 <Uri>/2010-04-01</Uri>
157 <SubresourceUris>
158 <Accounts>/2010-04-01/Accounts</Accounts>
159 </SubresourceUris>
160 </Version>
161 </TwilioResponse>
163 I introduced some formatting. Hmm, okay, Accounts. Let's check this out:
165 $ curl<?xml version="1.0"?>
166 <TwilioResponse><RestException><Status>401</Status><Message>Authenticate</Message><Code>20003</Code><MoreInfo></MoreInfo></RestException></TwilioResponse>
168 Okay, so I have to be authenticated. If I was, I'd get something like
169 this:
171 <TwilioResponse>
172 <Account>
173 <Sid>ACba8bc05eacf94afdae398e642c9cc32d</Sid>
174 <FriendlyName>Do you like my friendly name?</FriendlyName>
175 <Type>Full</Type>
176 <Status>active</Status>
177 <DateCreated>Wed, 04 Aug 2010 21:37:41 +0000</DateCreated>
178 <DateUpdated>Fri, 06 Aug 2010 01:15:02 +0000</DateUpdated>
179 <AuthToken>redacted</AuthToken>
180 <Uri>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d</Uri>
181 <SubresourceUris>
182 <AvailablePhoneNumbers>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/AvailablePhoneNumbers</AvailablePhoneNumbers>
183 <Calls>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Calls</Calls>
184 <Conferences>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Conferences</Conferences>
185 <IncomingPhoneNumbers>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/IncomingPhoneNumbers</IncomingPhoneNumbers>
186 <Notifications>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Notifications</Notifications>
187 <OutgoingCallerIds>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/OutgoingCallerIds</OutgoingCallerIds>
188 <Recordings>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Recordings</Recordings>
189 <Sandbox>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Sandbox</Sandbox>
190 <SMSMessages>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/SMS/Messages</SMSMessages>
191 <Transcriptions>/2010-04-01/Accounts/ACba8bc05eacf94afdae398e642c9cc32d/Transcriptions</Transcriptions>
192 </SubresourceUris>
193 </Account>
194 </TwilioResponse>
196 Awesome. I can see my all of the other resources that I can interact
197 with. Other than knowing how to authenticate, I can follow the links
198 from the endpoint, and discover their entire API. Rock. This is the way
199 things are supposed to be.
201 #### The bad
203 This:
205 $ curl -H "Accept: application/json"
206 <?xml version="1.0"?>
207 <TwilioResponse><RestException><Status>401</Status><Message>Authenticate</Message><Code>20003</Code><MoreInfo></MoreInfo></RestException></TwilioResponse>
209 Versus this:
211 $ curl
212 {"status":401,"message":"Authenticate","code":20003,"more_info":"http:\/\/\/docs\/errors\/20003"}
214 :/ Returning JSON when your resource ends with '.json' isn't bad, but
215 not respecting the Accept header, even when you return the right MIME
216 type, is just unfortunate.
218 ## ... and a little Announcement
220 It seems that this is a topic that people are really interested in. Part
221 I of this article was pretty well-received, and I got lots of great
222 email and feedback from people. It was also made pretty clear by [a few](
223!/wayneeseguin/status/97733413611638784) people that
224 they want more content from me on this topic.
226 So I decided to write a book about it. You can check out the site for
227 "[Get Some REST][7]", and put in your email address. Then you'll get
228 updated when I start pre-release sales.
230 So what's in "Get Some REST"? It's going to be a full description of how
231 to build RESTful web applications, from the ground up. Designing your
232 resources, laying out an API, all the details. I'm going to try to keep
233 most of the content language-agnostic, but provide code samples in
234 Rails 3.1, as well.
236 I plan on writing a bunch of content, and then releasing the book at
237 half-price in beta. Early adopters will be able to get their two cents
238 in, and I'll cover things they still have questions on. It'll be
239 available under a liberal license, in PDF, ePub, all that good stuff.
f8f6618 @steveklabnik ->
241 I've also set up a Twitter account at [@hypermediaapis]( I'll be tweeting updates about the book, and also other good content
242 related to RESTful design.
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
244 [1]: /2011/07/03/nobody-understands-rest-or-http.html
245 [2]:
246 [3]:
e86e775 @locks bad linkage
locks authored
247 [4]:
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
248 [5]:
249 [6]:
f8f6618 @steveklabnik ->
250 [7]:
ffde4c1 @steveklabnik Adding 'Some People Understand REST and HTTP'
Something went wrong with that request. Please try again.