Why REST Sucks

Let me preface this rant with a declaration:

Web services are great.

... but, I won’t beat around the bush. I hate REST.  REST is the most asinine attempt to ignorantly hand-jam arrogant assumptions about my desires as a programmer into the most unsuited mechanism possible: a transport protocol.

Let’s start with HTTP.  No matter what the authors’ intent, today HTTP is simply not much more than a high level transport protocol (I use “authors’ intent” because no matter what anyone tells you, HTTP as we know it today wasn’t conceived and formulated into specification by Tim Berners-Lee[1]. His team’s initial specification was sane and only included one verb: GET). HTTP effectively is a client/server request/response mechanism perfectly suited for a browser to request a resource from a server.  PERIOD.  And to all those who would say, “but no, it’s so much more.” I would say, you’re full of crap.  It’s not.  Stop.  No, really... Stop. 99.9999% of all HTTP traffic (I’d tack 10 more ‘9’s to the end of that number to be more accurate, but you get my point) is simply browser requests for a resource / server responses with the resource.  And that’s OK.  So just stop.  HTTP does a good job assuring a persistent URI reference to, and means to retrieve, a web resource; it allows me to assume a resource will remain at a specific location such that I can reference that resource from another resource, and now we have... The World Wide Web!  I love HTTP.  I would even say I love both GET and POST.  What I don’t love is REST trying to cram my entire programming model into 9 verbs.  Now don’t get me wrong, I think adding other verbs (besides GET) to maintain resources on the web is fine-- static HTML pages, images, XSD specs, even iCal through WebDAV is almost coherent. But trying to expose a public RPC interface for an entire complex software system architecture via 9 verbs is the closest thing to insane I can imagine.  It’s like trying to hack a programming paradigm out of the TCP packet header control bits! If URG is high then my calendar appointment is very important.  If ACK is low, then I’m denying your friend request.  It’s INSANE!

Here’s the deal.  We’re all complex programmers.  We dream up a lot of crazy crap.  Don’t try to shove our creativity into your world of CRUD (Create, Read, Update, Delete).  We’re not simply storing stuff on the web; no, we are doing stuff.

I mentioned before that GET and POST have their merits.  GET provides me with a nice, human-readable URL which can be used to repeat a simple request:

http://someserver.com/arbitrarySubcontext?someParam=1&someParam2=2

Great.  I know I’m referencing arbitrarySubcontext on server someserver.com and sending 2 parameters.  Wonderful.

What if the information in the parameters is big, and useless for human viewing-- like a uuencoded image, or the entire body of an email message.  Would I want that as part of the address in human sight?  Would I likely want to repeat that exact same request and receive the exact same response?  No, probably not; hence, POST.

But what about the other 7 HTTP verbs?

HEAD, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH

If you can accurately describe more than 2 of the above HTTP verbs, then you probably endorse REST.  Enough said.

Sure, we all get DELETE.  Some of us get PUT, but I’d bet hard cash you won’t get 2 identical answers when you ask us the difference between PUT and POST.  HEAD, TRACE, OPTIONS, CONNECT? Transport verbs for special cases or querying metadata!  PATCH is a nice nerdy Computer Science addition to U in CRUD.

So, basically we’re left with GET, PUT, POST, and DELETE to map my entire complex system software architecture into.  Back to my earlier rant: we don’t simply STORE THINGS... we DO THINGS!  My nouns don’t just exist!  They breath and join and search and jump and fart!  They DO THINGS!

The world of Computer Science has seen many leaps in design.  We went from Procedural Programming, to Object Oriented Programming, to Functional Programming (we kindof skipped Aspect Oriented Programming) and I’m sure in between I’m missing some favorites which you’ll all tell me about.  But hear me clearly.  RPC has been around and seen umpteen iterations, and with the exception of SOAP, REST is the absolute worst incarnation!  Summarily, REST is:

RPC + Object Oriented Programming stripped down to only allow classes 4 methods (GET, PUT, POST, DELETE).

Imagine if I asked you to design a complex system using an Object Oriented design pattern restricting your objects to 4 methods.

Now, here’s the sad thing.  REST advocates think REST is cool!

They think they’ve discovered some hidden knowledge the rest of us (no pun intended) haven’t figured out!  And they go around jacking with apache config files and playing in their little console windows running curl, hand crafting HTTP headers and they think it’s cool!  I hear things like: The Web was originally built to handle all of this, but no one ever uses it!  No frickin’ duh.  No one ever uses it because it sucks!

Look, web services in moderation (that’s another rant for a later time) are cool.  Noun/Verb URL semantics are a useful convention.  But please, please, just please stop trying to derive some closest-to-CRUD meaning from each method in my complex software system and pigeon hole that into the closest representation of GET, PUT, POST, or DELETE!  It adds nothing to the usefulness of the implementation and only takes away functionality.

“How does it take away functionality?” you might ask.  Well, let me tell ya 2 ways.  Just about all dynamic web content programming systems easily support POST and GET and most support retrieving provided parameters in the same way for either:

PHP - $_REQUEST['param1']
JSP - request.getParameter("param1");
ASP - OK, so ASP is stupid:
         Request.Form("param1"), or
         Request.QueryString("param1")
      .Form for POST?  Really? What if my <form method="get">?
      Stupid ASP.

All browsers support GET. duh.

What does this mean?  Well, it means that I can easily program all my web services to accept both GET and POST (normally without changing any of my server side code, to seamlessly accept either), and can test it simply with my browser… if I use a sane noun/verb URL convention like:

http://someserver.com/api/widget/get?widgetID=1&format=json
http://someserver.com/api/widget/get?category=jigs&detail=headers&format=xml
http://someserver.com/api/widget/recall?widgetID=1&urgency=high
http://someserver.com/api/widget/sendpromotion?widgetID=1&minPurchaseDate=20151231&promoWidgetID=2
http://someserver.com/api/widget/delete?widgetID=1

I can easily handle these without any web server tweaks, and using my server side environment de jour easily with, e.g.,

webapp/ROOT/api/widgets/get/index.jsp
webapp/ROOT/api/widgets/recall/index.jsp
webapp/ROOT/api/widgets/sendpromotion/index.jsp
webapp/ROOT/api/widgets/delete/index.jsp

I can add any number of verbs (methods) to my nouns (classes) because they are simply the last segment of my URL path, by convention-- the penultimate segment being the noun-- all providing a relatively straightforward class/method approach to exposing as web services most software systems.  It's easy to understand.  Easy to discover and browse and poke around by a potential user by simply turning on folder listings.  Adding "usage" output for endpoints when no parameters are passed can self document the API.  I can test these all out with my web browser.  I can demo these to would-be users of my API in a browser and give them examples for a method call simply by giving them example URLs.  Easy peasy-- except I hate peas.  Mushy peas are the worst.  They remind me of baby food.  Silly Brits.  You know they try to eat non-mushy peas balanced on the backs of their forks!  That’s almost as insane as REST! Almost.

Now, imagine the above example as a REST implementation:

http://someserver.com/api/widgets/widget/1
    HTTP Type: GET;
    Header: Accept: application/json
http://someserver.com/api/widgets/
    HTTP Type: GET;
    Header: Accept: text/xml;
            Content-Type: application/x-www-form-urlencoded
            Body: category=jigs&detail=header
recall
    ?
send promotion
    ?
http://someserver.com/api/widgets/widget/1
    HTTP Type: DELETE

The first URL is not obviously a search call and probably ambiguous if I wanted to simply list all widgets-- hack.  Clients wishing to designate the response format must construct an HTTP Header.  Delete requires the complexity of handling an HTTP type other than the commonly supported GET or POST.  The recall and sendpromotion methods do something other than simple CRUD on my object and since REST is built around the assumption that I wish to merely perform persistence (Create, Read, Update, Delete) and that actions on my nouns will do nothing more, then if I do have special server-side code to do something more, the client certainly wouldn’t expect it!  Every one of these methods requires jacking around with my web server to handle URL rewriting, so I can basically convert the url-part ‘widget/1’ into (what it should be) a parameter, ‘widgetID=1’,  and then choosing a different service handler based on the HTTP method.  None of this can be tested or demoed from a browser and all require you to drop to a shell and construct by hand HTTP Headers and Bodies and to become intimate with cryptic curl arguments.

Why?  Well because the Web was made to handle all this!  What a bunch of hog crap.

Look, it takes a sane, unenlightened human being about 2 minutes to come up with a useful OO-to-web-services mapping:

namespace/class/method?params...

Sure, it doesn’t handle stateful objects, but neither does REST “because the web should be stateless”-- yeah, go tell that to jsessionid, aspsessionid, and phpsessid... and I bet a few bright minds and a few more minutes could come up with some sort of UUID-per-object-instance-reference-stored-in-a-session-map convention to handle stateful in-session objects.  It’s not rocket science.  Stop trying to make it rocket science!

Web services are great, but please, let REST RIP.


1. https://hpbn.co/brief-history-of-http/

14
00

More Blog Entries

14 Comments

Hey, I just wanted say that I am in exactly the same boat. Except, I'm not really a fan of HTTP either. I hate the dogmatic BS that REST has become even more than I hate what it was conceived as.

00

Thank you for putting words on my frustration!

00
[...] Why REST Sucks 4 by icedchai | 0 comments on Hacker News. Advertisements Related [...] [url=https://hckrnews.wordpress.com/2018/12/17/new-top-story-on-hacker-news-why-rest-sucks/]Read More[/url]
00
[...] Why REST Sucks 4 by icedchai | 0 comments on Hacker News. Advertisements Share this: Click to share on WhatsApp (Opens in new window) Click to share on Facebook (Opens in new window) Click to share... [...] [url=https://worldtimes6.wordpress.com/2018/12/18/new-top-story-on-hacker-news-why-rest-sucks/]Read More[/url]
00
[...] Why REST Sucks 4 by icedchai | 0 comments on Hacker News. Advertisements Share this: Twitter Facebook Google Like this: Like Loading... Related [...] [url=https://latestnewsdesign.wordpress.com/2018/12/17/new-top-story-on-hacker-news-why-rest-sucks/]Read More[/url]
00

The idea of REST (state passed via requests and not in persistent server-side sessions) is a really good idea that lends itself to all sorts of benefits for scalability and maintainability. The real tragedy is that this good idea, which should be protocol agnostic, has been tightly and inextricably bundled with HTTP and hypermedia (the horribly named, and extremely constrictive HATEOS, for example). What we end up with is a post about "I hate REST" complaining (with merit) almost exclusively about the limitations of HTTP. 

 

HTTP is problematic. In my mind, there should be 4 "standard" verbs that are clearly defined: CREATE, GET, UPDATE and DELETE, and any number of possible custom verbs for other purposes. Then a standard like CORS, instead of relying on the awkwardly-named OPTIONS verb for preflight checks (and servers implementing OPTIONS endpoints exclusively for use with CORS), could instead define it's own custom verb like CORSCHECK or whatever. Then a lot of your complaints would be resolved: The URL represents the noun and you supply whatever verb makes sense for you, and you can build very complicated systems without having to endlessly override and over-complicate the 4 basic verbs. HTTP wasn't very forward-thinking and I wish it was better.

00

As you point out, if everything you want to do could be distilled to granular operations on a resource it would be fine but that’s just not the case. REST approaches the dogma of religion. If it really were as simple as claims suggest it is the descriptions of it would not assert it’s benefits but demonstrate them. Advocacy of the benefits entail some of the most muddled logic and descriptions I’ve come across.

 

Certainly stateless APIs scale but so do http bindings for a web service. Nothing special there. But abstraction is your friend and is as profound an advantage and means of simplification as is OO methodology. The rREST paradigm breaks down when you need to do anything more complex and perhaps transactional than operate on a single, granular, identifiable resource.

 

Protocol can be abstracted as can instancing, lifetime and more. Data communication can be rendered transparent and encapsulated rather than forcing yet another API into the mex with which one must build up from to implement a RESTful API. One gains simplicity by abstracting away transport and more and the only API becomes the one a given design calls for. Why should these matter or require one to grapple with anything at a low level.

 

Indeed there are implications in neglecting to use an underlying stateless protocol such as TCP/IP for a web service in the event of a connection loss but the best answer is not always to propagate the need for elemental operations to the client because that makes the client more complex. That’s suitable sometimes and not others. The need for state is a proverbial tar baby that sucks you into implementations that manage state such as session IDs. Scalability is not always needed and when it is state can be persisted on client systematically as is actually what’s happening in a so-called stateless and RESTful API.

 

As with anything you have to know what you’re doing and also the nature and limits of the problem you are trying to solve. In a RESTful application, if the client is is hosed you’re as screwed as you are as if state save on a server is lost.

 

RESTful APIs add a layer of client overhead in order to avoid having to take a more wholistic architectural look at trade offs that not all developers are equipped to do. That might be characterized as code more and think less.

 

Certainly RESTful APIs are one way to get the job done but few of it’s advocates are able to make the case for it because they’re unable to evaluate the trade offs. In their favor though is an ability to turn less experienced teams on a project and compensate for avoiding a few key approaches necessitating a thorough analysis of tradeoffs with more scut work which violates the DRY principle (I.e. Don’t Repeat Yourself).

 

00

Excuse the idiom scut, aka grunt

00

Totally agree. The designers and adherents of REST have evidently never heard of the lambda calculus. That thing which describes the operations of all code, which is based upon the function call, a verb and a set of parameters. If we could think of a way to make that simple and elegant thing as hard as possible between remote systems, with as much impedance mismatch to overcome as we can shove in, so the simple act of receiving and responding to a remote procedure call could require as many unnecessary contortions as we could likely get, that would be REST. I don't get the resistance to URI path as verb, POST body as parameters, done. 'But it doesn't follow the REST paradigm!' No, it doesn't, because REST is stupid, whereas message passing via some agreed upon IDL just works.

00

You pinned it down, man. Implementing some specification is natural when you're programming, but add to that the REST dogma hanging over your head: it makes my job less enjoyable, i'd rather be creating stuff than to satisfy some REST architect wet dream while implementing specs, while trying to be creative about my software. 

00

I totally agree.

00

Word up

00

I think REST caught on because in theory it was supposed to be some simple standard that in theory is easy to get started with and work with, and hard to screw up. In theory! It’s also a reaction to SOAP where we had this complicated framework and envelope metadata and had to read through all this ugly XML and so on. What do people do when stuck with something they hate, but instinctively run in the opposite direction? 

 

As a programmer from the old days of procedural and basic OOP (before OO was ruined and turned into a very hard to read and understand mess by crazy people making it all complicated with multiple inheritance, interfaces, reflection, etc.) I thought that the point and beauty of creating your own functions and objects was that you were able to build a system where the code became readable like a natural language. If you wanted your program to do something, you wrote a command whose name reflected that thing. 

 

REST on the other hand, in trying to reduce everything to fit into this minimal “CRUD” data transport system way of looking at things, has pretty much ruined programming by making developers bend over backwards to fit their business logic and applications into something that had NO resemblance to any kind of natural language or easily understood way of thinking. We might as well be programming in assembly language. 

 

Instead of intellisense and easy to use tools we are back to using primative methods to test and develop. And forget integrated verbose documentation! Swagger is neat with being able to run example code, but it is limited to very simple samples (when it even works with your firewall) and how do you use it to document bigger workflows and processes, with diagrams and fancy formatting? 

 

I was never crazy about SOA to begin with, and I know people are using REST to built working useful software, but the methods and the code itself is laughable. I have to think that of the people who use it are young enough to not know any different! 

00

I agree REST sucks but I don't like to see verbs in the url either, I'd prefer JSON-RPC with an additional "service" member to assist with routing.

00

Profile

null
Director and Sr. Software Architect