
REST Anti-Patterns (2008) - xparadigm
https://www.infoq.com/articles/rest-anti-patterns
======
strictnein
> Ignoring status codes

My favorite is when everything returns a 200, but the response is something
like:

    
    
       {
         status: "fail",
         error: "forbidden"
       }
    

Sometimes they even include the 403 in the response, almost like the developer
is giving you a giant middle finger.

~~~
dustingetz
A quick glance at history of HTTP can explain this without incompetence. HTTP
is fundamental to the world wide web and existed from the beginning in 1989.
Fielding's dissertation introduced the idea of REST in 2000. And REST became
part of mainstream client libraries in what, 2010? So there's a 20 year period
during which code was written against HTTP libraries which were not idiomatic
from a REST perspective. Returning status codes in the response body is a
common workaround for compatibility with code written in this 20 year window.

~~~
JimDabell
Status codes aren't something introduced by REST, they've been a standard part
of HTTP since HTTP 1.0. They've been in widespread use for decades. People use
200 for errors for a few reasons, but it's not because HTTP 0.9 didn't have
them.

~~~
mattmanser
I started programming professionaly in 2005 and I can assure you that back
then, outside of the browsers, people really didn't know or understand
response codes.

There's a load of early, popular, Stack Overflow questions that revolve around
what status to return when, and how to actually return those codes in your
language. For example, in ASP.Net/IIS it was actually quite hard to stop IIS 6
(?) from swallowing your 500 xml response and serving a custom html error
page. If I remember correctly some browsers didn't support PUT properly
either.

So while you are technically correct, the codes were in use, you are
historically wrong, few people outside of a small community understood their
use.

I remember this article from the first time around, when people were really
getting into REST and there was a fierce debate about strict REST Vs RESTful.
In reality RESTful has mainly won and this article was on the wrong side of
history.

~~~
JimDabell
> I started programming professionaly in 2005 and I can assure you that back
> then, outside of the browsers, people really didn't know or understand
> response codes.

> So while you are technically correct, the codes were in use, you are
> historically wrong, few people outside of a small community understood their
> use.

I started in the late 90s, and even back then they were commonly used. They
weren't just well understood by developers, but they were actually in non-
developer's lexicons as well. If you asked the typical geek back then what a
404 was, chances are they'd be able to tell you that it meant something was
missing. So I don't agree with you that they were understood by "few people
outside of a small community" at all. Using status codes has been standard
practice for decades. Maybe it took a couple of years at the beginning of your
career for you to notice them, but there simply wasn't this time period of
decades when they weren't in use until REST came along.

~~~
mattmanser
Given that ajax was only added to browsers in 1999 and AJAX didn't really
catch on seriously until 2003/2004ish, what you're claiming is at odds, again,
with actual history.

404s are a different matter because you'd get 404 pages, so it's not at all an
argument to support your position. It doesn't mean developers understood what
to return from an ajax call, or that they understood HTTP verbs.

I'll remind you again that it was actually fairly hard to return the correct
codes from a lot of frameworks, so objective facts are at odds with your
recollection of events.

I stick by my assertion that the vast majority of web developers in our
industry didn't really understand http until the latter half of the 2000s. I
also specifically remember presentations to all our developers both junior and
senior of how browser caching worked, which to most developers at the time was
a bit of a mystery, and the correct headers to return to control it.

Here are some examples from 2008 of developers on SO discussing things which
seem obvious today:

[http://stackoverflow.com/questions/165779/are-the-put-
delete...](http://stackoverflow.com/questions/165779/are-the-put-delete-head-
etc-methods-available-in-most-web-browsers)
[http://stackoverflow.com/questions/165720/how-to-debug-
restf...](http://stackoverflow.com/questions/165720/how-to-debug-restful-
services)

~~~
JimDabell
> Given that ajax was only added to browsers in 1999 and AJAX didn't really
> catch on seriously until 2003/2004ish, what you're claiming is at odds,
> again, with actual history.

Ajax is not the only way to access a web service.

> 404s are a different matter because you'd get 404 pages

…which are returned with a status code of 404. That's where the name comes
from. Non-200 status codes were ubiquitous even back then.

> It doesn't mean developers understood what to return from an ajax call, or
> that they understood HTTP verbs.

Ajax is irrelevant and we're talking about status codes, not verbs.

> I'll remind you again that it was actually fairly hard to return the correct
> codes from a lot of frameworks, so objective facts are at odds with your
> recollection of events.

Perhaps the technology _you_ were using made it difficult, but it certainly
wasn't the general case. PHP, classic ASP, mod\\_perl, mod\\_python, CGI
scripts… they could all respond with non-200 status codes easily. Which ones
are you thinking of that made it difficult?

> Here are some examples from 2008 of developers on SO discussing things which
> seem obvious today:

Come on man, clueless questions get asked about extremely well established
things on Stack Overflow every single day. That doesn't mean that those
concepts are suddenly no longer well understood, it just means that the person
asking is a beginner. And neither of those questions mentioned status codes at
all!

------
kbutler
The problem is that people want an RPC mechanism, and REST gives them a
document transfer mechanism.

If your API will never be navigated by a human operating a browser, a lot of
the REST specification is inapplicable (navigation links, etc.)

So you're throwing out a lot of REST regardless, and the question becomes
where to draw the line between ease of implementation and compliance with a
standard that doesn't really fit your needs.

~~~
wtbob
Another problem is that people want an RPC mechanism, when what they need is a
state-transfer mechanism.

It turns out that the semantics of RPC — attractive as they undeniably are —
are pretty poor for building real-world distributed systems, while those of
REST as a pretty good (or at least _better_ ) fit.

~~~
throwaway55523
People need both. REST works well for CRUD operations that don't have complex
side effects or constraints. What's often missing in this is intent. I just
want to do "the thing" to this particular account or whatever.

Personally I like to very selectively add RPC actions on top of the base
resource. Tacking an RPC action onto the resource URI allows you to
encapsulate the intent of the user's action, handle all the updates required
server side, and then return the updated representation.

~~~
boubiyeah
I almost always have both. I tend to use event sourcing and the intent is
mandatory. There might be 20 reasons to modify one resource, each with its own
list of side effects to later perform.

So it's usually POST resource/:id/action and that's fine.

~~~
naasking
> So it's usually POST resource/:id/action and that's fine.

There's nothing wrong with that. It's not anti-REST or anything, assuming you
satisfy the other REST constraints, ie. each request is self-contained and any
stateful resources are designated by URLs.

As an aside, I'm personally not a huge fan of human-readable URLs because it
encourages API consumers to rely on/construct URLs client-side, which is not
REST.

~~~
wtbob
I think a more properly-REST approach would be to PUT a representation of the
resource with the action applied. That is, rather than POSTing to
/resources/:id/close, one would PUT a closed version of the resource to
/resources/:id.

~~~
naasking
I don't see why that would be more REST. POST is to be used for side-effecting
operations, PUT is an optimization over POST for idempotent effectful
operations.

Certainly a PUT solution might have some advantages for replayability in case
of network partitions, but REST doesn't this choice dictate one way or the
other.

------
daliwali
The biggest anti-pattern of all: marketing your API as RESTful, when it is
really more RPC-like.

I agree on all points of this article. The only nitpick I have is that
tunneling through GET/POST is strictly necessary for HTML forms, since they do
not support other verbs.

~~~
deathanatos
> _The only nitpick I have is that tunneling through GET /POST is strictly
> necessary for HTML forms, since they do not support other verbs._

Only if you ignore AJAX in its entirety. Yes, the browser's capabilities are
limited, as it must be a common denominator and can't describe every
situation, and thus, can only GET/POST in certain forms.

------
dicroce
If API's are best represented via REST, then why aren't software API's in
general RESTful (e.g. I dont POST triangles to my GPU)? The answer: SOME API's
are best represented with REST, but most are not.

~~~
favorited
Because the concept of REST was specifically designed around HTTP, not to be
some abstract interface between any 2 systems.

~~~
yeukhon
I agree but also have counter example, perhaps not yet as an interface for two
systems. But let's start with this:

What if I can ask my OS to do things I normally do over some protocol like
HTTP in a RESTful style? Create user, list directory, find the last login,
tell me linux kernel version.

^ has been done as a separate monitoring tool like Osquery, but can't we make
such protocol natively? I don't want to parse my command-line output if I can
just speak in one human-readble, machine-friendly dialect.

~~~
coldtea
> _What if I can ask my OS to do things I normally do over some protocol like
> HTTP in a RESTful style? Create user, list directory, find the last login,
> tell me linux kernel version._

The /proc filesystem is somewhat close to that when it comes to GET.

> _I don 't want to parse my command-line output if I can just speak in one
> human-readble, machine-friendly dialect_

That's not what REST (the original concept) is about.

~~~
yeukhon
I understand REST's original motivation, but having a modern protocol to work
with resources on a computer doesn't seem too much to ask.

------
sopooneo
I believe REST as Fielding defined it has some great benefits. But I'm not a
purist. And actually, neither is the person who wrote this post. Because no
matter how much the disciples try to wriggle there way around it, using
cookies for sessions is not allowed.

"We next add a constraint to the client-server interaction: communication must
be stateless in nature, as in the client-stateless-server (CSS) style of
Section 3.4.3 (Figure 5-3), such that each request from client to server must
contain all of the information necessary to understand the request, and cannot
take advantage of any stored context on the server.Session state is therefore
kept entirely on the client." \- from Fieldings dissertation.

To be fully compliant you have to do use something like HTTP Basic Auth, where
you resend the username and password with each request.

I think you should use cookies to store a token that the server can then use
to determine whether the "context" of the request is "logged in" or not. I do
it. But it's technically a violation.

~~~
virmundi
I question that idea. Cookie is a standard header. So is Authorization. It's
up to the server to require either. Basic auth header removes the need for a
handshake to negotiate tokens. Authorization: Bearer (token) is now a
standard. I suppose Cookie: (token) could be too, but too many people felt
dirty.

My point is that Cookie does provide the credentials required for the call
contex, this fulfilling the self containment requirement.

~~~
sopooneo
As I read it, the problem is not the mechanism by which a session is
maintained, but the very existence of a session at all.

~~~
virmundi
I know that's what people think. But a JWT in a cookie doesn't strike me as
worse than basic auth.

------
marichards
Missing anti pattern: consider URLs insecure, especially if for a web browser.
Don't include customer details (name, email, account number, etc) or search
queries (free text) unless you have determined the security settings on your
logging, audit, proxies, .., all conform to data protection requirements that
suggest they should be encrypted and only visible to necessary staff. If you
expect pages to be bookmarked or shared, then consider the security impact of
where they are stored on local machines too, including in caches if your
company is silly enough not to enforce disk encryption for all users.

~~~
Sohcahtoa82
> consider URLs insecure, especially if for a web browser.

A web site I used recently puts your session ID in the URL. If you log in,
then alter the URL to remove the session ID, you appear logged out.

It gets even worse. Clicking the "Log out" button on the page simply removes
the session ID from the URL. If you go back and reload the web page with the
session ID in it again, you still appear logged in.

The page also doesn't use HSTS so is easily vulnerable to SSLStrip.

~~~
naasking
> A web site I used recently puts your session ID in the URL. If you log in,
> then alter the URL to remove the session ID, you appear logged out.

Nothing inherently wrong with that, but it depends on the situation.

> Clicking the "Log out" button on the page simply removes the session ID from
> the URL. If you go back and reload the web page with the session ID in it
> again, you still appear logged in.

That's bad.

------
yeukhon
My #1 complaint is there is no OOP client available from service provider.
i.e. building a driver to consume the response and turn that into your client
code. The irony is I often write my own harness for REST service, and those
are generally object-oriented, because I don't want to speak HTTP over and
over. Basically I built my a client while writing test, but I need to write
test to assert my client which was developed to help writing my test.

~~~
maxxxxx
SOAP works that way. But that has its own set of problems...

------
lloydjatkinson
Anti-pattern #1: Using REST. It's just cargo cult along with everyone
describing it and then implementing it differently. The only good part it has
is how to layout the URL, and even then it's just common sense.

~~~
chazu
One can't really fault REST for the flawed implementations - Fielding's thesis
is very explicit about what REST is and isn't.

Just because something becomes an often-misapplied buzzword doesn't say
anything negative about the original concept so much as the people mis-
implementing it.

------
jaequery
seriously i dont really care whether an api is restful or restish. at the end
of the day its all the same to me. just give me an api endpoint, request and
response objects nicely documented and i am golden.

------
throwaway18917
Have we considered that these REST "anti-patterns" exist because REST is
fundamentally inappropriate for what most people are trying to use it for?
What if you can't shoehorn your functionality into the handful of REST verbs?
What if none of the status codes make sense?

What ever happened to plain old RPC? Have we stopped to consider that people
tunnel things through POST or GET requests because it's easier and more
flexible than trying to cram your functionality into GET, POST, PUT, PATCH, or
DELETE?

If you find yourself using a lot of these anti-patterns, maybe you should
consider switching to something a little less "REST-ful".

~~~
niftich
Most things on the web are half-assed, and half-assed HTTP APIs enable rapid
results (before the problems start).

REST is not fundamentally inappropriate, it just needs a lot of careful design
about domain objects, link relations, and media types. Generally, people are
not very good at thoughtful design.

It didn't help that REST began to trend as an idea right around the same time
that intentionally schemaless JSON was replacing schema'd XML documents as the
preferred way of over-web information interchange. For consumers, schemaless
JSON snippets were attractive for partial processing; for developers, they
were attractive for rapid iteration. For makers of "Web 2.0 Mashups", JSON-
returning APIs were attractive because processing XML with circa-2006 "cross-
browser" nightmare-mode Javascript was about as pleasurable as pulling teeth.

People saw these APIs being called REST, they tried to understand REST, got
overwhelmed halfway through, called it REST-like or RESTful instead, and
that's how we arrived at where we are.

During this time, RPC wasn't cool or buzzword-compliant, so the people who
still RPC did it for good reasons and didn't really blog about it. The quip to
consider RPC is nonetheless valid; stuff like gRPC or Thrift are at least
proper RPC frameworks, and a much better idea than someone trying to ducktape
something with GET and POST for the millionth time.

Luckily, soon, GraphQL will be the newest entrant in this space, and will have
to contend an influx of superficially-informed people enticed by its promise.
It may have a better track record than REST, because a partial implementation
of GraphQL will better resemble GraphQL than a partial implementation of REST
will resemble REST.

~~~
coldtea
> _REST is not fundamentally inappropriate, it just needs a lot of careful
> design about domain objects, link relations, and media types. Generally,
> people are not very good at thoughtful design._

Especially if it's not worth the effort.

~~~
wtbob
Generally, people are not very good at determining if thoughtful design is
worth the effort.

Yes, waterfall was a mistake, but design-nothing is mistaken too. Thinking
before doing helps avoid waste & rework.

------
dang
Same title, different article from a few months ago:
[https://news.ycombinator.com/item?id=12479370](https://news.ycombinator.com/item?id=12479370).

~~~
saral
This provides a very concise and to the point explanation of the original
article.

