
REST was never about CRUD - elkinthewoods
https://tyk.io/blog/rest-never-crud/
======
lazulicurio
I know it's not technically correct, but the conceptual definition I've found
useful for myself is that REST is about operating on the HTTP layer instead of
building your own layers on top of it. Why create your own custom error
protocol when you can use HTTP error codes? Why develop your own caching
strategy when you can use HTTP caching? Why create your own authentication
mechanism when you can use HTTP authentication over TLS (or client
certificates, or etc.)? When the article talks about how REST should be
layered, cacheable, and client-agnostic, that's really the core of it to me.

By thinking this way, you can see how REST helps you re-use already-existing
infrastructure---proxies, load balancers, caches, etc.---instead of spending
time and effort making custom solutions. It also helps provide guidance as to
when REST may not be appropriate: can you answer those "why not HTTP?"
questions?

I've also found focusing on the resource/noun aspect (beyond considering
caching) to be a bit of a "nerd trap"; it's possible to spend a lot of time
chasing the perfect, "correct", solution. As the article notes, there's
nothing wrong with "verby" URLs as long as you are using HTTP instead of doing
your own thing.

~~~
wyuenho
> Why create your own custom error protocol when you can use HTTP error codes?

Because HTTP error codes are fixed and have well-defined meanings for HTTP
that may not map well to your application. Repurposing HTTP error codes
conflates your application-specific errors unless it maps to an exact subset
of one of the predefined errors.

> Why create your own authentication mechanism when you can use HTTP
> authentication over TLS (or client certificates, or etc.)?

Do you have a client cert? I've never encountered any server that supports
client certs in my entire 15-year career. Also, TLS is not a part of HTTP and
HTTP only supported Basic Auth until fairly recently.

~~~
stickfigure
_Repurposing HTTP error codes conflates your application-specific errors
unless it maps to an exact subset of one of the predefined errors._

...and beware even the errors that match exactly! I've seen multiple systems
in the wild that treat 404 as an application-specific error for "content not
found". It sounds perfectly reasonable at first, but it puts you one
misconfigured reverse proxy away from inadvertently broadcasting to the world
that all your content is gone.

This can have data-corrupting effects. If an external system deletes resources
via a reliable message queue and treats 404 as a success condition, they run
the risk of dropping these messages and creating an inconsistent state. I've
seen it happen.

Keep application-specific error messages distinguishable from the 'plumbing'.

~~~
cimmanom
That seems like a bug with the external system. 4xx means the request needs to
be corrected to achieve success. 2xx means success, even if success means
"deleted".

If a system treated 5xx responses as successful, you'd consider that a problem
with the system's response handling, not a problem with your own communication
of state. So why consider abuse of 4xx to be a problem with the communication
protocol?

~~~
stickfigure
The external system didn't define the API; the service did. If you poke around
on stackoverflow, you'll find quite a number of answers recommending this
pattern. It's a bad idea, but it's not uncommon.

~~~
eridius
Recommending what, that a `DELETE /foo/bar` should return a 404 on success?
That's flat-out wrong. It should return a 204 No Content. A subsequent `GET
/foo/bar` should return a 404, but presumably the message queue isn't doing a
subsequent GET but is inspecting the result of the DELETE.

------
mratzloff
The main problem with REST is Roy Fielding's communication style.

Here's a quote from a 2008 blog post:

 _Apparently, I use words with too many syllables when comparing design trade-
offs for network-based applications. I use too many general concepts, like
hypertext, to describe REST instead of sticking to a concrete example, like
HTML. I am supposed to tell them what they need to do, not how to think of the
problem space. A few people even complained that my dissertation is too hard
to read. Imagine that!_

Yeah, Roy. It's called being an effective communicator. Effective
communicators include stories and concrete examples to help bring the audience
along with them, instead of lengthy discussions of abstract concepts. Readers
shouldn't have to perform exegesis on your slideshow and blog to get even a
vague understanding of what you're trying to get at.

To be clear, any difficulty with REST in practice is a direct result of an
underspecified concept without a clearly defined RFC _as it relates to HTTP_.
Fielding didn't define anything about REST in terms of HTTP. All of REST, as
it relates to HTTP, has been an application of what other people think he
meant.

Nowhere in Fielding's 2002 academic paper[0], his 2008 talk at ApacheCon[1],
or his blog[2] does Fielding have clear examples or thoughts on the kinds of
specific details that Web developers often struggle with.

Fielding, in my estimation, seems principally concerned with three things with
regard to REST:

1) Every important resource has its own URI.

2) All interactions against that URI should be stateless and cacheable: all
application state that is specific to the user should live on the client
(e.g., local storage for browsers), and all shared state should live on the
server.

3) Interaction with that URI should be the same regardless of client (browser,
mobile app, etc.).

Everything else is left as an exercise for the reader.

[0]
[https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm](https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm)

[1] [https://www.slideshare.net/royfielding/a-little-rest-and-
rel...](https://www.slideshare.net/royfielding/a-little-rest-and-relaxation)

[2] [https://roy.gbiv.com/untangled/category/web-
architecture](https://roy.gbiv.com/untangled/category/web-architecture)

~~~
bmn__
> It's called being an effective communicator. […] bring the audience along
> […] Readers shouldn't have to perform exegesis

He's optimising for communicating with his peers: scientists and academic
researchers.

If you find this communication hard to digest, then chances are you are not
part of the intended audience. It is then mostly pointless to complain or try
to change his wording.

You can buy books from other people who deliberately target developers.

•
[https://oreilly.com/catalog/9780596529260](https://oreilly.com/catalog/9780596529260)
•
[https://oreilly.com/catalog/9780596801694](https://oreilly.com/catalog/9780596801694)
• [https://restinpractice.com/](https://restinpractice.com/) •
[http://www.designinghypermediaapis.com/](http://www.designinghypermediaapis.com/)

~~~
silverbax88
That's because they have generations of narrative dialog that is only intended
to be used in academia. They use superfluous and oftentimes nonsensical
language because they are attempting to create an environment of pseudo
intellect, where none exists.

~~~
jjaredsimpson
Is this parody?

------
jillesvangurp
Until AJAX happened around 2005, GET and POST were the only verbs you could
actually use in a browser. Before then, REST was not a really a thing. It used
to be that semantics of HTTP verbs had meaning in the context of e.g. caching
and other middleware. But now that everybody uses TLS, having caching proxies
acting as middlemen and interpreting http messages is not that common any
more.

REST was a nice idea when it got (re)invented about ten years after Fielding's
thesis but it left too much open for debate, ambiguity, and nitpicking and
quickly degenerated in different opinionated camps trying to retrofit new
ideas to the existing practices around http, which mainly boiled down to
interesting ways to do RPC.

Before HTTP, people were already long doing RPC using e.g. DCOM, CORBA,RMI,
etc. Reinveinting RPC over X has been the fate of pretty much every way we've
come up with to make two computers talk to each other.

~~~
naasking
> Before then, REST was not a really a thing.

You only need GET and POST for REST.

> Reinveinting RPC over X has been the fate of pretty much every way we've
> come up with to make two computers talk to each other.

REST isn't just RPC, it's RPC with specific constraints to enable caching,
scaling, adaptability, and distribution properties that unrestricted RPC alone
cannot achieve.

That's why REST is still important today, because RPC is _too flexible_ , and
RPC without constraints will inevitably run head first into all of the issues
that REST solves for you. Unrestricted RPC libraries then let you "solve"
these problems in myriad incompatible ways each with their own problems.

~~~
habitue
> Unrestricted RPC libraries then let you "solve" these problems in myriad
> incompatible ways each with their own problems.

I mean, this is exactly the state of REST today. It's not specified well
enough to admit general purpose clients (like, for example, GraphQL does)
because it's just a "pattern" not a specification.

Because every API has its own way of doing paging, subresource expansion,
expressing side-effectful operations, etc it means every API has a
corresponding custom-built client.

> Caching

Do these custom clients implement http caching? Not usually.

> Scaling

Arguably, REST is responsible for bringing about the rise of stateless API
servers. We should be grateful for the good idea, and not feel compelled to
adhere to the other aspects of REST if they don't suit our purposes.

> adaptability

Claims of additional adaptability in REST are usually talking about HATEOAS
where each resource defines how it can be interacted with by providing links
and semantic metadata etc. I will flat out say it: this doesn't work. Short of
building some intelligent agent into your API client, hypertext will never be
the engine of application state in any meaningful way. You can't just change
the links and have the client magically discover the right thing. Fielding's
thesis was talking about the web, where humans are the ones deciding which
links to follow. It's a useless concept in API design, and it adds tremendous
overhead for zero benefit.

~~~
naasking
> I mean, this is exactly the state of REST today. It's not specified well
> enough to admit general purpose clients (like, for example, GraphQL does)
> because it's just a "pattern" not a specification.

I don't think that's true. It's very well specified, it's just an _extensible_
specification admitting many possible hypermedia formats. There is no one
single hypermedia format to rule them all. Fielding's thesis was about the
architecture that allowed the web to scale, and content negotiation and
extensible content types are part of that.

> Because every API has its own way of doing paging, subresource expansion,
> expressing side-effectful operations, etc it means every API has a
> corresponding custom-built client.

This isn't necessary, depending on what you mean by "client". All such
operations should be encapsulated as links embedded within a hypermedia
format. The client needs only to know the high-level workflow or path to
navigate the hypermedia and extract the links it needs.

The hypermedia format itself can change, the links can change, but as long as
the path through the hypermedia is preserved, the client works. And there are
ways to increase adaptability even further if you don't want to hardcode a
path through a set of hypermedia documents, like a flat directory of endpoints
(but it's similar to the path, since there must be some shared semantic
knowledge about what you're looking for).

> Short of building some intelligent agent into your API client, hypertext
> will never be the engine of application state in any meaningful way. You
> can't just change the links and have the client magically discover the right
> thing.

It sounds like you misunderstand the use of hypermedia for autonomous agents.
Throw out HTML and consider a hypermedia format that has only two node types:
a named embedded link, and non-link data. An autonomous program can then
enumerate all links, or access specific named links it's interested in that
may be deeply or shallowly embedded within a web of hypermedia documents.

Most endpoints will probably be shallowly embedded, like with PWAs where the
JS simply does a form of RPC with the server. But if you consider more
complicated aggregated services, like interacting with someone's bank account
where the number of services is large and managed by separate teams (mortgage,
stock broker, chequeing, etc.), then it starts to make sense to require deeper
embeddings to permit better organization of your teams developing distinct
programs on the server-side.

The point being that REST gives you considerably more server-side flexibility
to do this.

~~~
coding123
> It sounds like you misunderstand the use of hypermedia for autonomous
> agents.

Every time you type hypermedia I want to punch you.

~~~
naasking
Exposure therapy is supposedly effective for anger problems, so let me help
you out:

hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia,
hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia,
hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia,
hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia,
hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia,
hypermedia, hypermedia, hypermedia, hypermedia, hypermedia, hypermedia,
hypermedia, hypermedia, hypermedia, hypermedia!!

------
beders
The comments here show that there's still much confusion about REST being an
architectural STYLE, not an actual architecture.

If you can present your domain as addressable representations of resources and
if you can lay out your business logic as changes to these resources, then you
could use REST via HTTP to provide access to your service.

Furthermore, if it is important to allow any client to connect to your service
and you don't have any control over the clients used, then adopting HATEOAS
provides a backward-compatible, future-proof way for client software to work
with your service.

If, OTOH, you have full control over the client-side, you can trade-off these
abilities for a simpler model (like GraphQL, if you must, or simple RPC over
HTTP)

Know what you design for.

Re Caching: Caching in HTTP is _very_ flexible. E-Tags basically give you
fine-grained control over how to cache and allow for significant
bandwidth/performance improvement. However, in many cases your app will also
benefit from an additional cache layer in your persistence layer. Don't
confuse them.

------
nostalgeek
It seems to me that REST "was never meant to solve web developers problems" at
first place and that dissertation wasn't addressed to them. I'm glad we are
getting out of REST. Devs need protocols and specifications, not vague
architectural ideas that leads to "you're doing it wrong" blog posts. There is
no "you're doing it wrong" with GraphQL, or SOAP, or JSON-RPC, you either
follow the spec or you don't.

~~~
vertere
Both well-defined protocols and vaguer design/architectural principles have
their place. But is it a great idea to take a bunch of such principles and
bundle them up under a (confusing) name? Perhaps not.

It seems to me that the initial popularity of "REST" was largely because it
wasn't SOAP (and didn't have to be XML), but it was still a name you could
give what you were doing that made it sound like you were following some sort
of standard.

~~~
silverbax88
I had zero issues with SOAP. I had zero issues with REST, although I couldn't
quite understand the proposed benefit. When people started moving to JSON, I
thought, okay, this is literally taking everything that already works and just
doing it in an even more complicated way.

It's not hard, but I see very few differences between them. SOAP is easier to
read/edit, JSON has less overhead/data, and REST...well, nobody could decide
what REST was, so they just made it up or ignored it.

~~~
mwcampbell
> I had zero issues with SOAP.

Just curious, what programming language(s) did you use to provide and/or
consume SOAP APIs?

~~~
cpburns2009
I'm not the OP but I've used Python with the _suds_ library to consume SOAP
APIs. I haven't had any problems with it other than companies deprecating
their SOAP APIs just to reimplement exactly the same thing with JSON.

~~~
mwcampbell
Ah, OK. I don't think suds existed when I first tried to access a SOAP API
from Python in 2004. If it did exist, it was certainly obscure.

Perhaps my own experience trying to use SOAP can shed some light on why REST
prevailed. In 2004, I tried to use the PayPal mass payment API from a Python
application (in the now-defunct Quixote web framework). As I recall, I found
one Python SOAP client library, but for some reason, I couldn't use it to
access the PayPal API. It was all just so complicated. In desperation, I ended
up writing a small service (micro-service?) to access the PayPal API using the
official PayPal Java SDK. That service used Jython, because I just couldn't
stand Java's verbosity. The main application communicated with the service
using XML-RPC.

Compared to SOAP, when I discovered REST, it seemed refreshingly simple, built
_for_ the Web rather than awkwardly abusing HTTP as a transport for an over-
complicated RPC protocol.

------
filleokus
After using GraphQL for over a year now I rarely miss the good old REST days.
Certainly the declaration of schemas/models in the beginning is maybe more
cumbersome compared to REST. But when that is in place is just so easy to work
with, no more adding extra field in responses to avoid doing multiple
unnecessary queries, just lovely.

When mutating state with GraphQL the suggested approach seems to be to have
"action based" endpoints, i.e "publishArticle", which resonates well with me.

~~~
jively
My biggest issue with GraphQL is the fact that what essentially used to be a
database operation has now become a (coordinated) batch API query. So the
operation has been split into microservices, then re-joined using a GraphQL
interpretation SPoF, all so that client business logic can be encapsulated as
a query string, instead of securing that effort as a specialised API endpoint.

Moving flexibility to the client comes with all the inherent risk of that
flexibility being available to (in a browser sense) a risky client.

RPC over REST is a solved problem IMO, arguments about REST RPC semantics
become ideological after a while.

~~~
rusk
_> RPC over REST is a solved problem_

I'm interested in understanding more about this statement.

Do you mean that all REST RPC libraries are sufficiently developed such that
you don't really need to worry about RPC being tricky, or that we all just as
a community understand the best strategies and common pitfalls. Or do you mean
a specific technology?

Just wondering cause whenever I hear the term RPC as an experience developer I
just shudder (-: Thanks!

~~~
jively
I meant that there are well discussed strategies for handling calls that are
RPC-oriented rather than CRUD, not that there are REST libraries that have
solved the problem.

Ultimately we find ourselves building 80-90% CRUD operations with edge cases
that don’t entirely fit with the straightforward RESTful toolset, and in those
situations making a call on how to handle it in code is a topic that has by
now been more or less discussed to death and becomes a stylistic choice.

REST isn’t a protocol, there is definitely interpretation at work.

I was using the term “RPC” to cover topics that are outside the scope of CRUD,
“do a thing” as opposed to “manipulate a thing”.

~~~
rusk
Thanks!

My own personal take on RPC being solved is that we're all pretty much agreed
it's not a good idea unless you absolutely have to!

(I mean RPC in it's more narrow definition as remote, synchronous function
calls - e.g. CORBA, SOAP, XML-RPC or the original Unix RPC protocol - for me
this is what makes the _resource oriented_ approach of REST a much more
appealing approach)

~~~
pdpi
> My own personal take on RPC being solved is that we're all pretty much
> agreed it's not a good idea unless you absolutely have to!

I'm very much of the opposite opinion — Ideally services are indistinguishable
from any other library, and the fact that they're running remotely instead of
locally only means there's a couple more (networking-related) error cases to
handle. RPC setups like Thrift or gRPC support this way of thinking relatively
well, whereas REST's resource/verb paradigm really forces your APIs to have a
certain shape.

~~~
rusk
_> Ideally services are indistinguishable from any other library_

I don't mean to be dismissive [0] - but that mindset seems a bit prehistoric
to me. We tried CORBA, everybody hated it, and it died!

Indeed, the bible on the topic [1] devotes substantial amounts of time to how
to structure your interfaces just so that you avoid issues arising from the
discrete system boundaries.

There is a world of difference between issuing an instruction that repositions
a program pointer from one position in memory to another, and transferring
execution from one compute node to another while _artificially blocking_
execution to _simulate_ a single thread of execution.

(Even, on a single machine with multiple cores this can be a problem - though
to a much more limited degree)

This is why we prefer loosely coupled, message-passing approaches, and
resource-oriented ones such as REST. This is why modern languages have
"futures" and "promises" (the implication being that we sometimes break
promises) and why functional languages are so much in vogue (specifying "what"
and leaving a substrate more sympathetic to the underlying architecture to
decide "how").

[0]
[https://en.wikipedia.org/wiki/Fallacies_of_distributed_compu...](https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing)

[1] [https://www.pearson.com/us/higher-
education/program/Henning-...](https://www.pearson.com/us/higher-
education/program/Henning-Advanced-CORBA-Programming-with-C/PGM30177.html)

------
zzbzq
Despite the architectural principals, it's named REST--REpresentational State
Transfer. It's really hard to twist and contrive a situation in which
"REpresentational State" is not CRUD. It can be done, but it's awkward. As
soon as you're doing non-CRUD operations, it's really hard to model them as
representations of state, and it's sometimes very unpleasant to use APIs where
the designers tried too hard to make the peg fit.

------
mi100hael
I disagree with the article and the examples provided.

The author has left out a few key components of REST in their initial
distillation. Critically:

 _> REST components perform actions on a resource by using a representation to
capture the current or intended state of that resource and transferring that
representation between components._

So given the example from the article:

    
    
        POST /articles/{articleId}/approve
    

This URL does not point to a resource, and the HTTP verb does not describe
what action is being taken upon a resource. It's also not using the
representation of a resource to capture intent.

It's also worth noting that a GET for the article would return the "status"
field and presumably other PUT requests to update the article would either act
directly on the article or have other vanity action URLs, making the API more
verbose than if everything were done properly.

A RESTful design would be in essence CRUD. It would have a url
(/articles/{articleId}) identifying a resource, it would have a representation
of a resource that includes a "status" field, and changing the status of the
article would involve a PUT request to the URL of the article with the desired
change of state.

~~~
macca321
It's a "request to approve an article" resource, even if it hasn't explicitly
been modelled that way.

~~~
mi100hael
By that logic, SOAP is RESTful.

------
coldtea
REST was never that good to begin with.

(Not even as originally intended, which is very different from RESTful way 99%
use it -- originally REST was all about self-reporting and discoverability,
which is not used, and irrelevant to most use cases).

Having JSON as the response, and a scheme to address entities, was good. Even
using HTTP action semantics was OK (though debatable). But that's far from
what REST is about.

Something like JSON-RPC would be a much better for web API needs.

~~~
sureaboutthis
That people misused REST is not what made REST "never that good" (in your
opinion). In fact, it was this misuse that frustrated Dr. Fielding more than
anything else.

~~~
masklinn
> That people misused REST is not what made REST "never that good" (in your
> opinion).

I used to be partial to that interpretation, but after a few years of looking
at it, at what people do and at what's actually valuable, I've come to the
conclusion that coldtea is correct: REST as originally intended was not that
good for programmatic contexts.

It certainly didn't help that it got quickly buzzwordified as "actually use
HTTP properly instead of just shoving your garbage through POST all the time"
(the original sin of SOAP or XML-RPC), but even then what makes "REST" work
for browsers (which is what the concept was extracted from) is that there is
an _intelligent agent_ doing the discovery and driving the interaction.

That's not useful for a programmatic API. You can add a discovery layer to a
programmatic API (as e.g. graphql schemas & explorer tools) but requiring
programmatic clients to go through such a discovery layer just makes
interacting with the API painful for no value.

Traversing a few pages when clicking around in your browser makes sense, doing
so from a programmatic client when you could literally just store the correct
endpoint and perform your call directly is nonsense: it's inefficient, it's
annoying and it's pointlessly verbose. Yet that is essentially what proper
rest as described and clarified[0] by Fielding require.

Even the "multiple interpretations" (multiple content types) option is
worthless when browsers don't provide the flexibility required to do content
negotiation[1] or leverage HTTP verbs beyond GET and POST.

[0] [https://roy.gbiv.com/untangled/2008/rest-apis-must-be-
hypert...](https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-
driven)

[1] even in places where they allow actual mimetypes it's as likely as not
they'll ignore it e.g. object/@type is a mimetype but no browser I know cares
about it, most of them send Accept: ∗/∗ and firefox sends its pagewise/default
Accept.

~~~
beders
> Traversing a few pages when clicking around in your browser makes sense,
> doing so from a programmatic client when you could literally just store the
> correct endpoint and perform your call directly is nonsense:

That requires implicit knowledge of the 'correct' endpoint. If that endpoint
changes or anything in between, you'll have to start versioning your API,
which basically tells all existing clients: Sorry, you got to update.

Allowing clients to discover resources is a future-proof way to keep your
client libraries compatible and evolve your API without versioning. It is more
work for the client and it is not always suitable. But if you intend to design
something future-proof (and we are talking about 10+ years), then REST has
already proven to be very successful (your latest browser can still browse a
web page from 15 years ago...)

~~~
masklinn
> That requires implicit knowledge of the 'correct' endpoint. If that endpoint
> changes or anything in between, you'll have to start versioning your API,
> which basically tells all existing clients: Sorry, you got to update.

In exactly the same way that the "RESTful" version requires implicit knowledge
of the content types: that knowledge it not implicit at all, it is
specifically and explicitly embedded in the system.

The word you're looking for is _static_.

> Allowing clients to discover resources is a future-proof way to keep your
> client libraries compatible and evolve your API without versioning.

That is completely untrue.

> But if you intend to design something future-proof (and we are talking about
> 10+ years), then REST has already proven to be very successful (your latest
> browser can still browse a web page from 15 years ago…)

Because it has a somewhat intelligent and flexible human driving it and able
to adapt in changes to the visited targets. Not so with a programmatic client.

------
LeonidBugaev
Agree. The whole point of rules is that you allowed to break them from time to
time.

During development with Rails I struggled a lot, because it was forcing CRUD
ideology in places where the custom route could work (and adding it was so
painful).

Standardization is fine, but usually it does not solve development issue, it
solves management issue, which is common for big orgs not small ones.
Especially when it gets on hype or forced by the top management, like it
happened numerous times, with latest examples of React, GraphQL or
Microservices.

~~~
wukerplank
Hm, I never found adding custom routes to Rails painful - could you elaborate?
Anyway, for smaller use cases I found Sinatra + ActiveRecord a great match.

~~~
LeonidBugaev
I'll be frank, the latest Rails version I used was Rails 3, and it was like 6
years ago, so I can't really remember details, except that I had to spread
logic to like 3 files to make it work. Maybe things changed.

~~~
yxhuvud
No, you didn't have to spread out the logic like that in Rails3. You could do
something like

    
    
        class AsController < ApplicationController
          def index
          end
    
          class BsController < ApplicationController
            def create
            end
          end
        end
    

with routes like

    
    
         resources :as do
           resources :bs, controller: "as/bs", only: :create
         end

~~~
ryanbrunner
Even that is resourceful routing, just with nested resources. Doing a flat out
custom route is even easier:

    
    
        class AsController < ApplicationController
          def custom
          end
        end
    

routes:

    
    
        resources :as do
          member { get :custom }
        end

~~~
yxhuvud
Yes, of course.

The whole point of my example was that it is possible to do resourceful
routing in a single file without having to resort to using custom routes. I
try to avoid custom routes whenever possible - in my experience they lead to
pain in the long run, more often than not.

------
coding123
My main gripe with REST is that it's totally not future proof. The notion of
RPC has been around forever. REST has basically completely replaced that. Http
status codes and REST URLs are not future proof. We have already seen superior
connection types (web sockets) come (and then basically go) that don't support
the notion of URLs and (well they do for a second, but after that the original
connection the URL is meaningless for the traffic flow). With Http2 we're
seeing the return of lightweight connections (basically similar to websockets
but have more graceful re-connection options). But http2 feels like a patch to
me. I don't really want to bind the future of Apps to a bunch of URLs. I'd
rather tie my app to a client that has a rich semantic set of objects and
methods that pull down data, can update data, etc...

When we use REST as our layer to convey the API itself, we really lock
ourselves down to a very specific set of URLs and HTTP Status codes. I'd
rather have a rich error object thrown, not an HTTP status code that I have to
examine.

I've had a pretty strong disdain for REST for the last few years and have been
actively finding replacements. The closest I can come up with is Grpc. I'm
dying waiting for Google to finish up Grpc-web however. If we continue to tie
ourselves to a bunch of server resources by URL we're going to take forever to
get off this archaic system that has no long term future.

~~~
ako
Do you think the web could have been built with RPC instead, and be just as
successful?

------
hirstys
Hmmm, but is REST so often conflated with 'just' CRUD, because that is all
people really want from REST, or is it that this perception is so pervasive
that people don't know what the potential is. Chicken or Egg? I'm saying Egg,
but I'm not saying which that relates to :)

~~~
clan
CRUD is easy to understand and close to the core of tasks that programmers at
large need to do.

Thinking in terms of REST requires that you concern yourself about the full
infrastructure. Many programmers i have met simply do not care. Super nice
properties such as cacheable and discoverable are outside their domain. Most
simply just want remote RPC.

Try convincing a programmer of the benefits of HATEOAS is though. It will be
dismissed as too much hassle with no real benefit.

But if you look at it from a data architectural perspective everything just
"clicks". Few projects are however approached from that angle.

~~~
tjpnz
HATEOS can be a weighty concept to get across and it never clicked for me
until I read a book on it. I still think there are aspects of it that could be
learned easily enough in isolation though. Understanding media types for
example allows you to develop some really nice schemes for API versioning. But
few people are even willing to learn that and just butcher their URLs instead.

------
fanf2
The draft BCP56 revision, on the use of HTTP as a substrate, is a nice primer
on REST API design

[https://tools.ietf.org/html/draft-ietf-httpbis-
bcp56bis](https://tools.ietf.org/html/draft-ietf-httpbis-bcp56bis)

------
billpg
The way I think of it is that GET, PUT, PATCH and DELETE all deal with data,
whereas POST is a call to action.

It is a little unfortunate that we don't have a CREATE verb (distinct from the
update-ness of PUT) and we need to use POST for this purpose.

~~~
0x445442
That's interesting. Are you saying that you view Posts as verbs/processes
which only result in side effects of the underlying system but do not change
the state of data? I'm trying to understand what you would consider the domain
of actions that would fall under your Post categorization. Batch Jobs,
Emailing reports etc.?

~~~
billpg
That's basically right. I view GET/PUT/PATCH/DELETE/CREATE as simple wrappers
around SQL commands, with validation and authorization checks.

POST is a call to do something with that data, which might include changing
the data. Off the top of my head, logging in, actions with external systems,
sending emails.

------
jstimpfle
An idea that I've never heard expressed explicitly is how REST is basically
distributed OOP. Both REST and OOP lead people to waste their time on
unimportant questions.

------
IshKebab
REST is kind of a worthless term at this point because really nobody agrees on
what it means.

I'm sure somebody will reply saying "no it clearly means _this_!" or "it
obviously means using HTTP how it was supposed to be used" or "those other
people just don't understand REST", but the fact is we still have articles -
in 2018! - that are trying to explain exactly what "REST" is.

~~~
jimjag
If people don't agree with what it means, it's because they aren't spending
time reading the actual dissertation. Instead they are kind of glancing over
it and depending on others interpretations to create their own. As someone who
writes protocol specs, Roy takes great care in being as clear as possible:
confusion, inconsistency and misinterpretation are not Worthy Things in
protocol implementations. To truly understand REST, you MUST understand HTTP
and the rationale behind it.

~~~
oftenwrong
Perhaps he should have written a specification for REST.

------
chronicler
I don't think anyone ever says RESTful services must be CRUD based, what they
say is non-crud operations are hard to model in a RESTful service.

------
niftich
REST as seen in HTTP has always been about resources (identified by URLs),
representations thereof that take the form of a particular mediatype (selected
explicitly or by content negotiation), and hyperlinks (with targets and rels).

When resources are obvious nouns already present in the backend's data model,
this maps well to CRUD. The problem comes when trying to describe complex
mutations, because to most people, this feels wrong, instilled by years of Dos
and Don'ts of half-baked lessons about Object Oriented design.

In all this time between when Roy's thesis was rediscovered to promote an
architectural style and when the trendiness of REST has finally run its
course, there were far too many posts complaining about deployments missing
hyperlinks (when usually, the API was externally documented, URLs templated,
and its clients hardcoded, making many usecases of embedded hyperlinks moot),
and not enough to reassure flummoxed designers that naming resources after
verbal nouns or deverbal nouns is perfectly fine. Oops.

------
lmm
The useful/valuable part of what came to be called "REST" (very little of
which is found in the dissertation, it's an accident of terminology which has
lead a lot of people astray) is all about CRUD, because CRUD is the only thing
that makes sense to do with a generic "resource".

~~~
icebraining
POST is used for way, way, way more than any CRUD operation.

~~~
lmm
Indeed it is, but at that point it's not "REST".

~~~
icebraining
Why wouldn't it be?

~~~
lmm
The HTTP verb isn't reflecting what's happening, and likely some important
considerations aren't being represented as entities.

~~~
icebraining
The description of the POST method is very generic; one of its functions
detailed in the HTTP spec is:

    
    
          - Providing a block of data, such as the result of submitting a
            form, to a data-handling process;
    

Which fits with much more than mere CRUD. And it's specifically written that
it doesn't have to result in the creation of a new URI-addressable resource.

(Also, REST isn't HTTP, you can comply with the former even if you're
violating the latter, and vice-versa)

~~~
lmm
> Also, REST isn't HTTP, you can comply with the former even if you're
> violating the latter, and vice-versa

Exactly. Complex processing via POSTs instead of distinct URI-addressable
resources is HTTP-compliant but not REST-compliant.

~~~
icebraining
I just don't see how it violates any of the REST constraints.

~~~
mi100hael
I think of REST imposing a certain grammar that HTTP alone doesn't necessarily
require. Remember, REST is resource-driven.

\- HTTP verbs are like normal verbs. They represent an action.

\- URLs represent the location of a resource or collection of resources.

\- Resources are like nouns. They represent what is being acted upon.

As soon as you start assigning different actions based on different URLs, the
HTTP verb no longer actually represents an action and the URL no longer points
to a resource.

~~~
icebraining
If you make an analogy, and then the analogy breaks, I'm not sure that shows
the flaw is in the original concept.

A RESTful architecture needs an Uniform Interface, yes, but their it's doesn't
have to be an "action" or anything specific. POST has a definition, and
everyone handling the requests can rely on it. That fulfills the constraint.

~~~
mi100hael
It's not really an analogy, though. If you have a POST request triggering some
random sequence of actions, what's the resource? What representation of state
is being transferred?

It's not REST, it's just HTTP.

------
lloeki
The author proposes:

    
    
        POST /articles/{articleId}/submit
        POST /articles/{articleId}/approve
        POST /articles/{articleId}/decline
        POST /articles/{articleId}/publish
    

I find this troublesome because the URL path component then includes a verb,
an _action_ , so there are two verbs in the same sentence!

This can be adjusted to:

    
    
        POST /articles/{articleId}/submitted
        POST /articles/{articleId}/approved
        POST /articles/{articleId}/declined
        POST /articles/{articleId}/published
    

Now the URLs really represent _resources_ on which HTTP verbs operate, and you
can readily guess what GET (if needed/applicable) on each resource would give
you.

There is some cognitive dissonance introduced by the inconsistency of
abstraction levels between the former "RPC style" (where HTTP verbs are mere
actuators† and the intent is in the URL and/or in the payload), and the latter
"REST style" (where verbs carry intent acted upon resources).

EDIT: I do not advocate for one over the other, merely that an API should be
consistent overall and not mix both.

† They are used as pure HTTP feature control (like caching) and do not carry
application-level semantics.

------
didibus
I'd like to implement such and API, but I feel often time its not that we
don't want to design an API that way, but that we fail to successfully
implement one.

I'd like to hear about guidelines, like for that transaction workflow example,
how would you implement this? What would be your data model?

------
guhcampos
I don't agree with the article (to me REST started about CRUD, and obviously
got overloaded with time), but that's not what I need to comment.

That font in the titles could have been gorgeous, but that upper case "D" is
offendingly bad.

~~~
hirstys
Ouch! Take your point, but don't you think the feels you get from the lower
case "about" in the title makes up for any failing in the "D"?

------
rhacker
I've been a long time fan of what this article is saying - but I didn't know
it was a thing. Now if I ever run into CRUDdy teams, I have something to share
with them :)

------
the_new_guy_29
Only one thing about this article i have to say is that its posted on TERRIBLY
designed page... Half of the screen black, align to the right and no "reading
view".

~~~
hirstys
Harsh but fair!? We're listening, feedback has been passed to the team who
look after [https://tyk.io/](https://tyk.io/).

------
ankurdhama
The same old story with anything called "architecture patterns", you can look
at them from different angles and each time you will have a new
interpretation.

------
OldSchoolJohnny
Half the page is a calendar widget?! This is the worst layout I've seen in a
long time.

~~~
hirstys
Harsh criticism Johnny! But we'll take it on board, feedback has been passed
to the [https://tyk.io/](https://tyk.io/) team, there is certainly an
opportunity to adjust proportions here. As a matter of interest, which
blog/article page layout do you really rate?

~~~
OldSchoolJohnny
I think I was that emphatic because I couldn't believe anyone would want to
exhibit such an obviously flawed design in public until it was fixed. I'm
still confused how this would make the light of day, but I guess esthetics and
usability are something learned perhaps over time?

------
pas
This is an oft revisited topic, and it might be worthwhile to cite a few
paragraphs from Dr Fielding in order to support and expand upon the submitted
article.

"Search my dissertation and you won’t find any mention of CRUD or POST." [0]

> For example, some APIs may need to support actions such as submit, approve,
> and decline. With our somewhat limited action verbs in HTTP, how can we add
> this to our API?

By representing the difference in states. Or otherwise. The communication
medium is not the API. ("A REST API should not be dependent on any single
communication protocol, though its successful mapping to a given protocol may
be dependent on the availability of metadata, choice of methods, etc. " [1])

> POST /articles/{articleId}/publish , POST /articles/{articleId}/submit , ...
> etc.

A few years ago I was zealously advocating against representing actions in
URIs, and using a generic /actions [sub]resource, but this actually makes it
simpler to represent the available actions to the client. And sure, this can
be thought of as REST via the code-on-demand part of the architecture. The
server points to a script (it doesn't have to be JS, but the media type must
be defined in the REST API), that can understand the available actions from
the state representation, and construct the necessary representations for the
desired actions. (So in a HTTP API, the JS interprets the JSON and knows how
to put together POST requests to modify the resources, without the actions
having been reified and URI-fied in the JSON.)

> The workflow our API supports is more explicit, [...]

Sure, that's pragmatic, but after much gnashing of teeth and scratching of
heads, REST is about presenting options to the client by offering various
media types (content-types), and letting the client request the best
representation, and not really about a fixed ACL neither about fixed flow.

From [1] again: "A REST API should spend almost all of its descriptive effort
in defining the media type(s) used for representing resources and driving
application state, or in defining extended relation names and/or hypertext-
enabled mark-up for existing standard media types. Any effort spent describing
what methods to use on what URIs of interest should be entirely defined within
the scope of the processing rules for a media type (and, in most cases,
already defined by existing media types). [Failure here implies that out-of-
band information is driving interaction instead of hypertext.]"

[0] [https://roy.gbiv.com/untangled/2009/it-is-okay-to-use-
post](https://roy.gbiv.com/untangled/2009/it-is-okay-to-use-post)

[1] [https://roy.gbiv.com/untangled/2008/rest-apis-must-be-
hypert...](https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-
driven)

~~~
dnomad
> "A REST API should spend almost all of its descriptive effort in defining
> the media type(s) used for representing resources and driving application
> state, or in defining extended relation names and/or hypertext-enabled mark-
> up for existing standard media types. Any effort spent describing what
> methods to use on what URIs of interest should be entirely defined within
> the scope of the processing rules for a media type (and, in most cases,
> already defined by existing media types).

Arguably this is the problem: what Fielding is describing here has a well-
known name: Object Oriented Analysis and Design. It's not at all clear why a
new formalization was needed when we already have Objects. Resources have
URIs, Objects have memory addresses. Resources have representations that are
defined by content media types, Objects have behavior that are defined by --
types.

> POST /articles/{articleId}/publish , POST /articles/{articleId}/submit , ...
> etc.

Good ol' OOAD can avoid nonsense like this. It's immediately clear that the
Resources identified by these URIs aren't real objects. If you want to talk
Published Articles vs Submitted Articles you would introduce new types and new
repositories.

The only way this makes any sense is:

POST /articles/published/ POST /articles/submitted/

Only now does 'GET /articles/published/{articleID}' make sense and we might
think about what that content media type looks like vs submitted articles.

~~~
pas
It looks like this is a case of the stereotypical academization. Fielding
looked at the Web, and abstracted it, and calls it REST Architecture.

And of course, the problem is that nobody sits down to just do a quick World
Wide Web API for an app, or an internal corporate business-as-usual thingie.
In fact since the original hypertext project at CERN no one every did it. We
still use the same Web, incrementally transformed into what it is today, but
still the same HTML, same Content-Types, and HTML1.0-like markup. All eaten
and excreted by JavaScript of course, but that's a prime example of something
incremental, and not exactly thought out.

Moreover, there's not much to say about media types driving interaction,
because 99.9% of the Web is GET GET GET. And OPTIONS (due CORS) is driven by
out-of-band conventions (defined in the Fetch and the amended XHR APIs, but
not much to do with media types - but of course, CORS is more about fixing the
leaky encapsulations of the communications interface/layer, not about the
content [the high level state being transferred]).

~~~
LoSboccacc
> Fielding looked at the Web, and abstracted it, and calls it REST
> Architecture.

yeah the perfect rest protocol is the web and the perfect rest clients are the
humans that navigate the action represented on the hypermedia.

that said, there's some value to be had in discoverability, even if rest
grossly gloss over how to discover parameters for the action that the state
holds.

~~~
masklinn
> that said, there's some value to be had in discoverability, even if rest
> grossly gloss over how to discover parameters for the action that the state
> holds.

There absolutely is and API systems like graphql have taken that to heart
(playing with a graphql explorer is delightful).

But forcing all programmatic interactions through a "discoverability" layer is
not useful, yet that's essentially what REST (as originally formalised)
mandates.

------
sureaboutthis
Many years ago, Dr. Fielding would visit a forum or two and offer answers to
questions about REST. I had a number of my questions answered directly by him
which helped me through the years to discover how many people have no clue
about what REST is and how to use it but wave the REST flag as if they did--
and they don't.

I believe Roy quit visiting forums for those reasons; a frustration dealing
with all that.

~~~
coldtea
Words are not defined by their creators, they are defined by their usage.

Those people indeed know what REST is -- in fact, they define what REST is.
When we talk about REST, we talk about how people use it.

They might not know what "REST as defined by Dr. Fielding is" but that's not
really relevant to them or to the industry at large.

~~~
nacnud
"use", not "usage". </joke>

~~~
coldtea
Not according to my dictionary:

use: the action of using something or the state of being used for a purpose.

usage: the action of using something or the fact of being used: a survey of
water usage

~~~
itscaleb
Words are not defined by their creators, they are defined by their use.

Those people indeed know what USAGE is -- in fact, they define what USAGE is.
When we talk about USAGE, we talk about how people use it.

They might not know what "USAGE as defined by coldtea is" but that's not
really relevant to them or to the population at large.

:-)

