Problems with RESTful APIs (2015)
This article is a complete strawman. His description of a supposed &quot;REST&quot;ful API is the least RESTful API I&#x27;ve seen in a while:<p>&gt; <i>The what-we-actually-indended-to-use request method embedded in the request payload, e.g. DELETE</i><p>Don&#x27;t do this.<p>&gt; <i>The what-we-actually-indended-to-use response code embedded in the response payload, e.g. 206 Partial content.</i><p>Don&#x27;t do this!<p>&gt; <i>If you’ve ever worked with a RESTful API, you know they are almost impossible to debug.</i><p>You&#x27;re begging the question.<p>There exist <i>plenty</i> of APIs that abuse the HTTP methods and status codes, which I feel like is really the core argument being made. But completely ignoring it and what its purpose is is throwing the baby out with the bathwater. Read and understand the RFCs for HTTP, for a start; unfortunately, I&#x27;d wager that far too many devs of ostensibly RESTful APIs do not do this, and it shows when you get a response with a status code that makes zero sense. The vast majority of HTTP APIs I&#x27;ve interacted with violate both the semantic meaning of the methods and that of the status codes. (GitHub&#x27;s is about the best I&#x27;ve ever seen.) A &quot;RESTful HTTP API&quot; is an API that uses the mechanisms in HTTP to accomplish the ideas of REST; (i.e., I&#x27;m not trying to equate HTTP and REST, I just think abuses of HTTP are a major impediment to understanding REST. Using HTTP well will naturally help you accomplish REST.)<p>&gt; <i>can anyone out there explained to me what 417 Expectation failed really means?</i><p>You&#x27;ve not read and understood the RFCs for HTTP. 417 Expectation Failed is obvious if you have; an expectation (on the request) failed (cannot be met by the server). An &quot;expectation&quot; is denoted on the request through use of the &quot;Expect&quot; header. The only existing expectation is 100-continue. Even if you do not know this by heart (and I don&#x27;t expect that), it&#x27;s <i>readily</i> findable:<p>1. Google &quot;http rfc status codes&quot;; unfortunately it&#x27;s the second result; Google doesn&#x27;t understand that the second result is an updated version of the first. Regardless, if you go for the first result, it points you to the second (-ish, b&#x2F;c the RFC was split into multiple).<p>2. You select &quot;417 Expectation Failed&quot; in the Table of Contents.<p>3. You read the extremely straight-forward explanation. If you don&#x27;t understand what the Expect header is for, the RFC links you to it.<p>So what are the ideas of REST? Start at its (de-)acronym: &quot;Representational state transfer&quot;. That is, transfer of <i>a resource</i>. A &quot;resource&quot; is just an &quot;object&quot; or a concept, a thing — the actual concrete thing represented by a resource is going to be determined by your domain specific problem. E.g., &quot;a user&#x27;s profile data&quot;, &quot;a message in a thread&quot;, &quot;a news article&quot; are all &quot;resources&quot; in that they embody some concept or idea that we want to communicate the underlying state of. You also need a standard, or <i>uniform</i> method of uniquely identifying, or <i>locating</i> these resources, which is what a URL is for (you then see why it&#x27;s lit. uniform resource locator). So we build URLs to stand in as names for resources.<p>In order to transfer the state of a resource, embodied at a URL, you need to send it across a wire. You need to serialize it into some <i>representation</i> that&#x27;s going to get transferred. That&#x27;s what HTTP is supposed to help you do.<p>If you <i>were</i> writing a RESTful API, embedding things like the status of the operation in the response body should feel wrong, because the status isn&#x27;t conceptually a part of the resource you were trying to operate on in the first place; go back to our example of &quot;a post in a thread&quot; — whats a status got to do with that? While technically, yes, HTTP&#x27;s entity body is capable of transferring arbitrary binary data, the end result of using it that way results in simply the re-invention of wheels, such as needing to signal the success or failure of operations on resources. HTTP&#x27;s purpose, alongside the ideas of REST, is to pull out the common bits that occur when writing code that transfers representation of stuff around, such as, e.g., caching, getting an ok to transfer large content prior to writing it all out to the wire, knowing the status of the operation, or pagination of collections of resources. (I cannot count the number of times I&#x27;ve witnessed API designers reinvent pagination, badly!)<p>The manner in which people like to use HTTP, with effectively only GET and POST (<i>maybe</i>!) is more akin to RPCs to me. It works. You can do that. But you then need to handle caching, pagination, status of operations, etc. on your own, and you&#x27;ll end up, I believe, reinventing HTTP. Doing a lot of that (I think, and I think this was Roy&#x27;s original point) is more effective if you structure your operations around transferring representations of resources around; this is especially visible in caching, because in caching you <i>need</i> the representation of a resource, because that&#x27;s what a cache works with by its very nature. (As opposed to, say, making opaque method calls on a remote instance.)<p>Go read [1]; nothing really in there is bound to HTTP, just that HTTP makes a lot of it easier. Also, while I understand that Roy has a lot of arguments around how representations should be hypertext — and I agree with them, mostly — I think that comes <i>second</i> to the ideas that:<p>1. A URL represents a resource<p>2. The point of GET &#x2F; PUT &#x2F; DELETE is to transfer the state of that resource.<p>If you don&#x27;t understand those two points, I don&#x27;t think you&#x27;ll understand the arguments behind hypertext.<p>[1]: <a href="http:&#x2F;&#x2F;www.ics.uci.edu&#x2F;~fielding&#x2F;pubs&#x2F;dissertation&#x2F;rest_arch_style.htm" rel="nofollow">http:&#x2F;&#x2F;www.ics.uci.edu&#x2F;~fielding&#x2F;pubs&#x2F;dissertation&#x2F;rest_arch...</a><p>The other points,<p>&gt; <i>They are easy to debug since transaction information is found in easy-to-read JSON inside the payloads using a single, domain specific vocabulary.</i><p>Pushing everything into an opaque blob removes the ability for any tooling to pull out high level information. Chrome devtools, httpie, etc., all disprove this point.<p>&gt; <i>Problem #1: There is little agreement on what a RESTful API is</i><p>I agree. I also feel like too many people who think they know have not read anything from Roy Fielding, or even the HTTP RFCs.<p>&gt; <i>The REST vocabulary is not fully supported</i><p>depends mostly on<p>&gt; <i>most client and server applications don’t support all verbs or response codes for the HTTP protocol. For example, most web browsers have limited support for PUT or DELETE. And many server applications often don’t properly support these methods either.</i><p>This isn&#x27;t true: JavaScript in all browsers in respectable use supports this; Android and iOS fully support HTTP; most server-side development languages have excellent tooling for this. This is a completely false statement, and requires proof, or at least a concrete example to back it up. (Were it true, it only invalidates the use of HTTP as an aid to accomplishing REST.)<p>&gt; <i>Problem #3: The REST vocabulary is not rich enough for APIs</i><p>POST is, essentially, a catch-all for odd operations not supported by other verbs.<p>&gt; <i>Imagine we create an application where we want to send a “render complete” response back to an HTTP client</i><p>If we have a resource that represents a rendering job, if you GET a representation of that render job, it can include some indication of completeness. The bigger problem here is actually HTTP&#x27;s polling, IMO. Websockets might serve <i>this specific example</i> better, but this singular example doesn&#x27;t invalidate that most web APIs boil down to CRUD $object of $type, which HTTP supports phenomenally well.<p>&gt; <i>Problem #5: RESTful APIs are usually tied to HTTP</i><p>Well, yes. At the end of the day, it <i>has to be tied to something</i>. HTTP is a pretty good something, with decent tooling.<p>&gt; <i>They use only one response code to confirm proper receipt of a message - typically 200 OK for HTTP.</i><p>Yes, you can send a single bit back. HTTP attempts to be a bit more rich than this. E.g., if something is in progress, and attempting to retrieve the data I just stored will fail until some serve-side job is complete, HTTP can easily signal this. Muxing them into 200 OK removes that information.<p>&gt; <i>They completely separate the response content from the transmission mechanism. All errors, warnings, and data are placed in the JSON response payload.</i><p>HTTP already has this: the response content is the body of the response. The transmission mechanism is HTTP. I don&#x27;t want errors, warnings, etc., in the payload, where they are opaque and unusable by common tooling.<p>&gt; <i>They can easily be moved or shared between transmission channels such as HTTP&#x2F;S, WebSockets, XMPP, telnet, SFTP, SCP, or SSH.</i><p>These channels do not support transferring the state of something. (Okay, HTTP does.) telnet is a mostly dumb pipe, same for SSH. You would need to build some custom, non-iteroperable layer on top of that. HTTP is the standardized version of that.