
Do you really know why you prefer REST over RPC? - mmastrac
http://apihandyman.io/do-you-really-know-why-you-prefer-rest-over-rpc/
======
andrewstuart2
> Both RPC and REST use HTTP protocol which is a request/response protocol.

Neither REST nor RPC is tied to HTTP at all. I think the title alone of
section 6.3 of Fielding's dissertation, "REST Applied to HTTP", [1] should be
enough to convince anybody that they're completely orthogonal concepts, much
less the rest of the actual dissertation. The Wikipedia article for RPC [2]
also provides numerous examples of RPC implementations that never even touch
TCP, much less HTTP.

REST is literally just transferring some state via a representation. RPC is
literally just calling a procedure remotely.

Also, yes, hatred of expecting different behaviors from different verbs is
irrational. Because verbs indicate actions, and different verbs indicate
different actions. It works well in written/spoken language, and it works well
in REST _and_ HTTP.

[1][https://www.ics.uci.edu/~fielding/pubs/dissertation/evaluati...](https://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_3)

[2][https://en.wikipedia.org/wiki/Remote_procedure_call](https://en.wikipedia.org/wiki/Remote_procedure_call)

~~~
resu_nimda
_Also, yes, hatred of expecting different behaviors from different verbs is
irrational._

To be fair, you've kind of rephrased her point into a strawman that's simply
opposed to the abstract concept of verbs.

Most of the time, people understand URLs as a one-to-one mapping - each URL
has only one meaning, one website. It's not until you actually start writing
code to create or consume an HTTP API that you need to learn the concept of
the different verbs. In spoken language you don't become functionally fluent
with the language and then some time later have a new concept of verbs
introduced. So I can understand why the idea that "actually a URL (the part
that everyone sees and knows) can have multiple meanings based on this hidden
parameter" can feel wrong.

~~~
andrewstuart2
In defense of the way I phrased that, here's the direct middle section of his
tweet: "... different behaviors based on the verb..."

It's very very deliberately called an HTTP _verb_ , for a reason.

It's not that I expect the average person, or even a new developer, should
know that HTTP verbs exist or that URLs and URIs literally locate and identify
resources in a uniform way. The part that bothers me is that when you
deliberately write a blog about the subject that other developers may see and
take as credible, you ought to put more effort into making sure your
information is accurate before publishing.

------
DrJokepu
But REST is RPC. I've read the article and the author basically defines RPC as
a HTTP API that doesn't use the HTTP methods in a semantically correct manner
but that's not what RPC is. RPC is any remote procedure call. It doesn't even
have to be HTTP-based. Message queues are an example of something that's not
RPC.

~~~
sixdimensional
I agree with you. Too many get carried away with REST and don't think beyond
HTTP.

I do appreciate the author's work here, I think the author was trying to help
people clarify that REST/RPC don't need to be exclusive and that is helpful.
All too often we encounter developers who want to sound smart and cool and
state that it is "this tech" or "that tech" or NOTHING!

At a higher level of abstraction, representational state transfer should have
nothing to do with HTTP semantics. It just so happens that we attribute REST
with being related to HTTP semantics. But you could do REST with a non-HTTP
protocol, if you wanted, why not?

Similarly, you can use a non-HTTP protocol in any other kind of framework for
network based communication that you wanted...

And it just so happens that RPC is exposing functional, encapsulated units of
code via network protocols and TCP/UDP sockets.

I remember trying to write my own network protocols for fun before over TCP
and UDP sockets. Simple things like an echo service or a simple client/server
application protocol. Doing that helps give one context for REST, RPC, SMTP,
FTP, and more - semantics, concepts and frameworks over network connectivity.

The OSI model still matters.
[http://en.wikipedia.org/wiki/OSI_model](http://en.wikipedia.org/wiki/OSI_model)

------
xrstf
One point of doing REST instead of RPC is because you shouldn't re-invent the
wheel. HTTP already has verbs and identifiers, so why create another set of
verbs (the RPC methods)? REST is embracing HTTP to its fullest, RPC[overHTTP]
is "just" taking advantage of HTTP's ubiquity across platforms.

[Edit: I don't mind having a few RPC-style endpoints in a REST API. The
world's not a perfect square and sometimes things just don't fit the resource-
driven model well. But for example, for performing logins (something which I
previously did via "POST /login"), I switched to doing a "POST /sessions",
because that's what a login it is: adding a new session.]

~~~
coldtea
> _One point of doing REST instead of RPC is because you shouldn 't re-invent
> the wheel. HTTP already has verbs and identifiers, so why create another set
> of verbs (the RPC methods)?_

Because HTTP's verbs weren't created with arbitrary operations in mind, but
for specific, HTTP-related tasks.

------
ecopoesis
I actually prefer RPC. It's not very often I'm making a call to a server that
I don't want to have complex logic behind. The REST paradigm doesn't fit that
(though you can wedge it in).

REST GETs are fine for getters, and I generally like REST URLs because their
prettier and don't have god-function smell like you get with SOAP.

But for commands, a POST with params to distinct URLs for each command works
fine.

------
avodonosov
REST as "representational state transfer" is a boolshit. The real reason it is
popular - it allows to communicate via HTTP, just URLs everyone understands
and many tools available, even web browser can be used.

If you remember SOAP - the crazy approach to web services promoted before
REST, you understand the difference REST made.

The same way AJAX is not about XML, REST for me is not about "representational
state transfer", but just about using URLs to request operations from server.

The original REST idea of using HTTP error codes and forbidding application to
create its own error classes and error reporting convention just doesn't work.
HTTP errors only meaningful for HTTP - a transfer protocol, not for arbitrary
application.

The point of using different HTTP verbs - chaching. Don't do

    
    
       GET /deleteItem?itemId=456
    

because it's not guaranteed to reach the sever. Use POST instead.

So, I use HTTP URLs to communicate with server, and don't care to follow REST
dogmas. It's more similar to what article calls "RPC" (actually RPC is more
general term, in particular including SOAP).

~~~
hessenwolf
Feel free to expand those explanations... :)

~~~
avodonosov
Not much to add.

The REST culture gives us some regularity. If we read github API, or google
API or facebook API, we know what to expect - that they will use GET to
retrieve an object, DELETE to delete an object and so on. It's good there is a
convention helping to study new things.

Another good property of REST culture - it prevents people from building thick
layers on top of HTTP. While not everything can fit into HTTP (at least error
reporting, in my opinion; HTTP error codes are not enough), this culture helps
to keep APIs simple.

~~~
collyw
Other than the verbs used, there isn't very much regularity. Try plugging a
back end REST API into a front end framework. In my experience you always need
an extra library.

------
bluepnume
I generally use a pattern like:

GET /api/resource

POST /api/resource/action

Where 'action' is something a bit more descriptive than 'PUT' or 'DELETE' or
whatever. Kind of like an object-oriented api... I'm still always dealing with
resources, but I have custom actions for specific use cases.

~~~
3pt14159
Why would you do this? It makes no sense.

By (mostly) adhering to REST patterns you get so much stuff for free. Other
developers can quickly get up to speed quickly. Client libraries are easier to
write. Things like Ember Data work out of the box. I agree that every now and
then doing a POST to /logout is easier than doing a DELETE /access_token/23,
but a consistent API is far more worth it.

~~~
leeoniya
the problem with HTTP REST verbs is that not everything can be (or should be)
represented as a resource.

a simple example is a one-click payment + order action. you're creating
multiple records in different tables - payment gateway transaction log,
payment table, an order table, probably creating a customer record, sending
email notification, logging a conversion, etc.

that sequence of actions does not adhere neatly to any HTTP verbs. it can be
more clearly called "processorder" because it involves a lot more than
creating an order record in a table. if you'd like, you can of course do POST
/orders, but the nuance of what's happening is unnecessarily lost.

another example is a taking that order and marking it as "shipped". it is not
a simple PATCH /orders/123 shipped=true. the front-end does not know all the
fields that must be set in all the places on the backend. it is in fact a
series of actions that take some data from the front, and some from the back
and do a bunch of things that represent the setShipped() sequence.

HTTP verbs were designed for managing documents, for which they work well.
They also happen to map well for direct db entries via CRUD. but trying to
shoehorn them into all aspects of complex web apps is misguided. a true RPC is
often what is necessary.

~~~
pekk
"Buy this" might create multiple records in different tables, but there is no
requirement that one URL in a REST API corresponds directly to one record or
one table. The REST API does not have to expose the entire sequence of under-
the-hood actions. This does not somehow require RPC to address.

~~~
leeoniya
how would you differentiate a direct CRUD route with one that performs a lot
of additional things?

PATCH /orders/123 shipped=1

what does this do? does it simply set a field or does it trigger a shipOrder()
sequence that also sets that field? what if you need the ability to do both
(eg: admin interface & customer frontend)?

I understand that in this case you can instead do something like:

POST /shipments order=123

but not everything has a record backing it that would yield to this pattern.
the response to a POST is supposed to be a Location header of the created
record, so in fact you do need some form of URI and record for the created
shipment.

HTTP REST's multi-item and hierarchical item management are also very hacked-
in and necessarily too chatty. You cannot return multiple Locations in a
header, for example, when multiple records are created. Strict adherence to
the purity of HTTP verbs and limits quickly degenerates into custom hackery
above and beyond the RFCs for anything mildly complex.

~~~
hartror
I think some these statements aren't right:

> the response to a POST is supposed to be a Location header of the created
> record

The HTTP spec says otherwise:

    
    
       The action performed by the POST method might not result in a
       resource that can be identified by a URI. In this case, either 200
       (OK) or 204 (No Content) is the appropriate response status,
       depending on whether or not the response includes an entity that
       describes the result.
    

> You cannot return multiple Locations in a header, for example, when multiple
> records are created.

Again the HTTP spec allows you to manage this (though not in the header):

    
    
       10.2.2 201 Created
    
       The request has been fulfilled and resulted in a new resource being
       created. The newly created resource can be referenced by the URI(s)
       returned in the entity of the response, with the most specific URI
       for the resource given by a Location header field. The response
       SHOULD include an entity containing a list of resource
       characteristics and location(s) from which the user or user agent can
       choose the one most appropriate.
    

Source:
[http://tools.ietf.org/html/rfc2616](http://tools.ietf.org/html/rfc2616)

edit: was quoting HTTP 1.0 rather than 1.1

~~~
leeoniya
thanks for the corrections.

but here is a perfect example of multiple ways to do the same thing. and the
custom additions to HTTP REST begin: multiple locations in the body of the
response. the fact that sometimes the headers are sufficient, but at other
times, you have to just create your own API to fill in the missing
functionality using the response bodies.

no me gusta.

------
xirdstl
I prefer to call my APIs RESTish. That way, I can avoid never ending debates
about whether some particular feature of my API conforms to REST.

~~~
ryan-allen
Who would have thought that there's more than one way to skin a cat? Or maybe
REST is the best chuck out the rest! Pun intended!

I like your approach because it avoids never ending debates.

~~~
xirdstl
How about PREST? Pragmatic REST?

~~~
pekk
Post on Hacker News, 2016: "Pragmatic REST is not REST at all"

------
qsymmachus
One point that didn't get addressed in this article is the use of HTTP status
codes to indicate the result of a request. REST encourages proper use of
status codes – 404 for a missing resource, 422 for invalid data, 201 for
successful resource creation, etc. – further enhancing the predictability of
the API. How does RPC handle status codes?

~~~
MichaelGG
Eh, sorta. Send an invalid body, say an unavailable product ID, or an invalid
quantity. What error will you return? HTTP codes and REST might make sense for
some simple scenarios (like managing files), but it breaks down fast
otherwise. Shoehorning everything into the few codes HTTP has seems pointless.

~~~
lloeki
400, 422 (or even 404 if the product id was part of the resource URL). That's
not shoehorning, that's using something which defines a crude yet semantically
consistent granularity, that does not prevent having more detailed errors in
the response body and/or additional headers. So I get a level of abstraction
for free, increasing consistency in semantics and behaviour both inside my API
and outside, easing debugging and allowing me to use off-the-shelf HTTP
components (including curl) while leveraging common knowledge of the protocol
across applications.

The pet peeve issue I have with RPC/HTTP APIs is that people keep reinventing
HTTP on top of it, only badly (at which point they may as well use RPC/TCP).
That's why I like REST/HTTP, because I can "reuse things" when the problem
model fits well within that tool (and it very often does). If REST/HTTP
becomes a constraint instead of an asset, then maybe one should not use either
REST or HTTP, _and I 'm fine with it because that was not the tool for the
job_.

This is a tool, not a religion.

------
NateDad
REST is great for CRUD, and easy from javascript/web pages, but it sucks for
non-CRUD actions (like logout a user or reboot a machine), and it is not as
friendly as RPC for consuming from client libraries.

I have designed both, and I find that the contortions you have to do to make
your API RESTful is generally not worth it unless you're almost entirely CRUD
and are mainly targeting the browser (and even then, you probably have a lot
more nonCRUD actions than you think).

For everything else, RPC wins because you design it much like regular code.

Maybe the answer is just to use both, rather than trying to jam a square peg
in a round hole.

~~~
andrewstuart2
I'd say the tricky part is modeling _state transitions_ in REST. Rebooting is
a transition between states as is logout.

Instead of defaulting to RPC, I like to try a few things:

1\. Find some abstract resource that represents. POST to reboots to create a
new reboot. In order to faithfully bring the resource into parity with the new
state you've requested, the system reboots a machine. A GET to reboots should
give you a list of previous reboots. Updating a reboot record might
occasionally be necessary as well if an error occurred.

2\. Model the state transition as simply another state. "Rebooting," for
example, might be a state you can transfer that represents on -> off -> on.

I'll admit they don't roll off the brain as easily as calling the "reboot"
procedure, but I also typically find that it brings a good amount of positives
as well. For example, the ability to create reboots brings with it the ability
to get a record of those reboots pretty trivially (if you're storing
requests).

~~~
Programmatic
My first approach for this is to POST to a reboot/ resource which gives you a
reboot/123 ID that you can continue to do a GET against to see the status of
the reboot (did it start OK? Is the machine back up?).

------
jasoncrawford
The Richardson Maturity Model, as explained by Martin Fowler, is the only
explanation of the benefits of REST that has ever made sense to me:
[http://martinfowler.com/articles/richardsonMaturityModel.htm...](http://martinfowler.com/articles/richardsonMaturityModel.html)

And for what it's worth, I've only found value in levels 1 and 2, not level 3.

Also, this talk by DHH helped me understand how to organize an API by creating
more nouns with a restricted set of verbs, instead of proliferating verbs on a
smaller set of nouns:
[http://www.bestechvideos.com/2007/08/12/railsconf-07-keynote...](http://www.bestechvideos.com/2007/08/12/railsconf-07-keynote-
david-heinemeier-hansson)

~~~
hartror
Why do you not find value in hypermedia? Do you have tightly coupled servers
and clients?

~~~
jasoncrawford
Yeah. Are there any examples of a generic client that doesn't know what data
or API to expect? I don't know of any.

------
kevincennis
In my experience, it's way easier to write client apps against a REST API.

If you look at frameworks like Backbone, you can basically create
models/collections for a simple CRUD app just by adding some values to a
declarative hash (URI, primary key, etc.). Because everything is so
predictable, it's really easy to specify a default behavior.

Granted, you could certainly do something similar with an RPC API, but I still
think it would likely be harder to generalize.

------
ozten
A missing factor is fragility in the face of change.

RPC leads to fragile protocols. Adding arguments to a procedure or adding
properties to a result can often break clients and in practice you update
systems lock step.

HTTP can gracefully handle different API version requests to the same
resource. REST clients are encouraged to take only what they need from the
representation.

Also, I strongly disagree with the Totaling points section. Seems too "nice"
to both sides.

------
hartror
It seems to be that many of the comments on this and other API posts recently
are by people who have never had to integrate with some else's "mostly REST
but only when it suits me" API.

If the API you are writing has these features:

* you are the consumer as well as the author.

* no other developer is ever going to need to understand it.

* don't care about server/proxy/library support.

by all means don't bother with REST.

But if you are doing one/some/all of the above implementing a HTTP REST
architecture is going to make your life and fellow developer's lives easier.
That is what specifications are for, there to make things easier for everyone.

The thing I find most frustrating about these discussions is REST is such a
simple architecture with a well thought out technical reasoning. Yet people
happily ignore parts of it because of some unstated preference, and develop
their own architecture which other developers then have to divine.

~~~
guelo
Let's say you have to integrate with my API that uses GET /user?id=1 instead
of /user/1 , How have I made your life worse? Is it going to cost you any
extra time at all to code it up?

~~~
jbergens
People usually miss the references that should be encoded within REST
responses, The hypermedia part. You should be able to call /user/ and get a
list of users whith links to the specific users. This link will be in the
correct http-format which means you can discover the api from one or a few
starting points. This gets even more obvious when you try to fetch a sub-
resource or call a "method" on a resource. Those links are encoded within the
resource itself. That means when you get a user record it may contain links to
things you can do with it (add an address or an extra email, get specific
details etc). With SOAP it is only naming and there is very little
recommendations about that.

~~~
guelo
I guess what I object to is this concept of discoverability. No matter what,
you need documentation to discover these initial endpoints, so why not
document the whole API? SOAP had mechanical discover ability with WSDLs but it
didn't really work. The reason REST won was because it was simple for humans
to understand, which means mostly that the documentation is simple to read. As
long as the URLs follow some simple consistent pattern that developers can
implement without convoluted effort it should be fine, no need to follow some
rigid philosophy. If the documentation is missing some key actions I doubt
most developers are going to go poking around hoping to discover undocumented
endpoints, they'll probably end up contacting the developer to tell them
they're API is broken.

------
Geee
Actually, the URL pattern doesn't define if your API is RESTful or not. You
can use similar URL patterns in RPC too. This would be non-RESTful:

    
    
        POST /users/create
        POST /users/1234/read
        POST /users/1234/update
        POST /users/1234/delete
    

Also, in REST you don't have to use this URL pattern. Just make sure that your
resources have their own URLs. In addition, resources don't have to map into
your database. E.g.

    
    
       POST /new_address_due_to_move.php?customer_id=1234, 
    

is RESTful, although a bit of a stretch. My line of thought is that if you
would have a separate form in your web page, it should be a separate resource
with it's own URL where the form data is POSTed.

------
barrkel
If you have a 1:1:1 relationship between database models, in-memory models and
the REST endpoint, and the primary purpose of the API is to manipulate these
entities, there's a reasonably strong stylistic benefit to REST style. Not all
applications are like this, but many bread and butter CRUD apps are.

------
RangerScience
Hmm. Seems to me that this actually relates well to the object-oriented versus
functional programming "debate" \- REST deals with things (like OO), RPC deals
with actions (like functional).

But, in my experience, most requests consist of a "thing path" \- host,
resource; and then some "function" \- get, update, other. POST is then the '='
\- it's still a function under the hood, but because of it's commonality and
interaction with language, the syntax is a little special.

In which case (and this is what I see in the APIs I most like) "the right
thing to do" is to combine them, where you have pure REST when you're
interacting with the object, but use RPC style when you're interacting with
the object's actions.

Let's say I have some machinery exposed through an API, you might do:

GET host.com/machines/1 -> {"machine":"mixer","state":"off"} POST
host.com/machines/1?state:on -> 200

because I'm interacting with its state. But if I need to interact with its
functional actions:

POST host.com/machines/1/mix?substance1=h20&substance2=c02

it makes more sense to phrase it as an action. "I want you to start doing
this". You could also phrase as a request for a state transition: POST
host.com/machines/1?state:mixing&substance1=h20&substance2=c02

but (to me) that seems way weirder, generally.

I've got to go, but I think the answers change you go from physical resources
to virtual ones, say, things that process information -

GET host.com/stock_analyzer/6/analyze?ticker=GOOG

where you might control state variables regarding the analysis algorithms
using a REST-style.

Thoughts?

~~~
grandalf
> REST deals with things (like OO), RPC deals with actions (like functional).

I think it's the opposite: REST deals with data, while RPC calls an operation
that has side effects on some (potentially) unknown state.

Not arguing that one is better just offering my thoughts on the analogy.

~~~
delinka
That looks to me like you both agree. Things==data and actions == "calls an
operation"

~~~
marcosdumay
The main problem is that function != action.

~~~
arde
Exactly. Action is imperative, not functional.

------
yxhuvud
> If a user want to stop using your service, you’ll do this (not so obvious)
> call:

> DELETE /users/1234

No! It would be

    
    
      DELETE /sessions/12345
    

or possibly

    
    
      DELETE /users/1234/session
    

or even

    
    
      DELETE /users/1234/sessions/3
    

in the case a user can have more than one concurrent different sessions (this
is actually a fairly common case for the application we do were I work. We
don't use http for this though).

Unless you actually want to permanently stop the user from using the system,
in which case

    
    
      DELETE /users/1234
    

would be the perfectly obvious choice.

------
aggieben
The OP has essentially used circular logic: RPC is as good as REST because I
know how to use it to address the issues that REST addresses (which I doubt,
incidentally).

This to me is like arguing that object-oriented programming isn't really any
better than procedural programming because I know how to write well-structured
procedural programs. This is completely beside the point, which is that
procedural programming as a style _tends_ toward balls-of-mud programs (to
simplify things), and object-oriented techniques were conceived of in order to
address the characteristics of procedural programming that are the cause of
this tendency.

I view RESTful API programming in a similar vein: RPC also has negative
tendencies (such as the creation of fragile protocols), and REST addresses
many, if not all of those. Most of the time for more people, RESTful
techniques will lead to better service and API design than will RPC, just like
for most of the people most of the time, object-oriented programming will lead
to better programs than will procedural programming.

------
mrinterweb
I'm amazed that when talking about RPC that schemas never came up. Schemas are
probably my favorite part of RPCs. Let's say you have multiple services that
need to communicate, but testing interoperability between the services is
tricky. RPC type enforced schemas (interface definition language (IDL)) are
great for this because the schemas provide guarantees that the services are
communicating correctly. If a system starts seeing exceptions about IDL/schema
errors, then you know right away that things are broken. Writing tests that
can assume that RPC method calls will be enforced.

Another thing that struck me strange about the article is showing the RPC
urls. When I was using Thrift, I never needed to think about URLs. I just
needed to make sure that I was calling methods correctly.

I think RPCs are a good fit for organizations looking for a way for their
service based architecture to communicate. I don't really like exposing RPCs
as a public API or for web clients to interact with.

------
pjungwir
I really like REST most of the time, but I do have some complaints about
Rails' implementation of it. I wrote about them a few years ago:

[http://illuminatedcomputing.com/posts/2011/07/restless-
doubt...](http://illuminatedcomputing.com/posts/2011/07/restless-doubts/)

Basically, after form submit errors your location bar still says /widgets or
/widgets/1 rather than /widgets/new or /widgets/1/edit, so bookmarking that
page, or "like"ing it, or Ctrl-L + <Enter>ing are all broken. I'd much prefer
a redirect back to the correct URL.

Also the distinction between "create" and "update" can break the back button,
if the user creates something, then clicks back to edit their submission
(because submitting a second time will create a second thing, not update their
original thing). That's not Rails so much as REST in general.

~~~
seanp2k2
Not sure if I 100% understand, but it sounds like maybe you want to rescue the
exceptions you can think of explicitly, then redirect_to previous_thing and
return

~~~
pjungwir
Exactly. Something like this:

    
    
        if @foo.save
          flash[:success] = "Saved"
          redirect_to foos_path
        else
          redirect_to new_foo_path
        end
    

The standard pattern is to `render 'new'` rather than doing the latter
redirect. So I'm complaining that my preferred way isn't "blessed" by the
Rails community. Also you need a trick to keep @foo.errors in between requests
and load it up in your #new method the second time around.

------
meric
I like how when building REST API servers and clients there are standard
components that just works. The entire API in the same format means it is easy
to write a DSL across the entire API configure each endpoint - such as row
level and field level permissions, pagination, filtering. If you have a well
designed RPC you have the same benefit, but except with REST - you can reuse
someone else's work because the design is the same. It literally takes 20
seconds to change the _/ user/_ endpoint so:

1\. Non-authenticated users can create users, and see a list of users with
details that are public.

2\. Authenticated users can view their own public and private details and have
read/write access to most fields except _is_staff_.

3\. Staff users have full permissions for users that belong to the country
they are managing.

4\. Superusers have access to everything.

Without the benefit of DSLs this would take hours to write all the if/else
statements and unit test them. It would be a nightmare to do the same for all
your endpoints. I assume you can write some abstraction functions to use for
all your RPC endpoints but it'd be easier to reuse a library from past
projects that had the same REST API design.

Example:

Row level:

    
    
        permission_classes = [
            Or(And(Or(IsOwner('id'), IsStaff), IsUpdateOnly),
                And(AllowAny, IsReadOnly),
                And(AllowAny, IsCreateOnly))]
    

Field level:

    
    
        is_public = And(IsActive, Is('is_public', True))
        fields = {
            'display_name': [],
            ('is_active', 'password', 'email'): [
                Or(is_staff_or_owner, IsCreateOnly)
            ],
            ('full_name', 'slug',): [
                Or(is_staff_or_owner, is_public, IsCreateOnly)
            ]
        }

------
mpdehaan2
I started developing network apps before REST existed -- probably like many
people here, that wasn't long ago, SOAP, various things like RMI and then
XMLRPC were things. SOAP was never good anyway, deeply buried in standards
committee goo. But there are still things I miss from these things. When I
found XMLRPC after doing all these things, it was very much a "WOW" moment.
(JSON of course, with it's definite differences between maps/hash-tables and
lists, is greatly superior to me).

A generic problem with REST APIs is they all handle collections, associating
items with subcollections (including establishing and removing 1-to-many or
many-to-many relationships between existing objects), query strings,
authentication, and pagination very very differently. Not all APIs are
discoverable either, many don't do structured error codes. Thus to talk to
one, rather than just using _client-library_ , more work has to be done, often
repeated work in multiple languages. Lots of REST APIs aren't well
discoverable and rely on special logic to form up URLs, and many have weird
verb pollutions - modelling a long running job for instance, I've typically
have done as posting a job descriptor to a job collection, because the
standard verbs don't really apply.

All being said, I prefer a nice broweseable REST API, but despite the accursed
"XML" in the name, XMLRPC was easy - there were bindings in multiple languages
and it was easy to ask an API what methods were supported. Problems came in
the undefined parts - like whether "None" could be passed, and so on.

I can design and build some very elegant REST APIs, but the clients DO have
work to do, every time. A good example for me was trying to write to GitHub's
API, and then being angry at the way pagination was overcomplicated and URLs
were not discoverable. (It might have gotten better).

BTW, if you are doing Python and want a GREAT foundation in pagination,
discoverability, and so on, I recommend Django REST framework. One catch is
you may wish to extend some of the serializers to return URLs relative to
other URLs.

I don't think RPC is evil so much - over HTTPS and backed by a good webserver,
and done so that it's stateless (something a pre-forking webserver (esp with
MaxRequestsPerChild in play in Apache) forces you into, not so much REST
protocols all by itself), I think it's just not socially acceptable.

So statelessness good, having to write client-specific "flavors" of REST,
well, it's just reality.

(In other news, I'm disappointed all my He-Man figures got sold in the 80s so
I can't illustrate tech cartoons with them, well done)

~~~
smacktoward
_> SOAP was never good anyway, deeply buried in standards committee goo._

IMO SOAP in its very early days was actually fairly pleasant, at least when
compared to the existing alternatives (things like COM and CORBA, which, ew).
XML-RPC was also nice, in a "keep it simple, stupid" kind of way.

Then of course SOAP crushed XML-RPC, the crew of the USS Enterprise got their
hands on it, and the rest is (depressing) history.

~~~
marcosdumay
I've met SOAP when IBM was already pushing it, thus I may have completely
missed the early days.

But I never even imagined I'd hear somebody say SOAP was more pleasant than
CORBA. Yes, working with is CORBA barely better than hitting your foot several
times with a hammer, but relative to SOAP, it's a breeze.

Anyway, it's kind of depressing that even now the best RPC we have to show is
REST. It's a problem that looks so simple from a distance, why can't somebody
build something really great here?

------
colordrops
This seems to me to be a debate between equally usable technologies. The
differences between REST and RPC are slight enough that it won't make a big
difference which you go with. To spend too much time on this would be bike
shedding.

~~~
Zikes
Tabs vs Spaces

Emacs vs Vim

Destined to become one of the great debates of history.

------
cwbrandsma
I might be behind on state of the art these days...but my current api has no
GET requests, everything is a POST. So in that term, we are not restful.

We had a couple of problems with GET requests: all of our data ended up in the
url (we have too much info that has to be passed, we stopped working on some
browsers), and the data returned could be cached (which is a HUGE problem for
us).

Now, POSTs can also be cached, but there are easy ways around it...you can do
the same thing with a GET, but that means adding more information to the url.

Anyway, one we got to the point of forgoing all GET requests, we ended up just
doing everything with a POST for simplicity.

~~~
xrstf
I did the exact same thing in a project of mine. We're shifting away from that
and put our data in cookies, so we can cache some of the things our API send
out.

~~~
nulltype
You can also use localstorage these days. It's great not having to send data
on every request.

------
ams6110
I don't think GETs should ever change state. I'm fine with all other
operations being POSTs though. If nothing else it provides compatibility with
clients that don't support all the HTTP verbs (yes there are some)

~~~
k__
How do you manage big queries with GET?

~~~
karmajunkie
By query, are you referring to the querystring/url size?

Practically speaking, I don't know if I've ever had a querystring that was
effectively too large, busting some browser-determined limit. If you did, you
might as well use a POST instead of GET, because the request is unlikely to be
cacheable (I'm assuming the reason its such a large string is that you're
serializing a large form of values or using the querystring to persist state
in some way [protip: this is a bad idea]), which is the main reason to prefer
GET for the request. POST (according to HTTP semantics, _may_ have side
effects, but is not _required_ to have side effects).

IMHO, the choice between HTTP verbs beyond GET vs everything else is mostly
bikeshedding. As a convention its fine, but there aren't a lot of pragmatic
technical reasons to go with one over the other (referring to PUT vs PATCH vs
POST), despite the HTTP semantics.

~~~
k__
No, it just was a very flexible data-retrieval API and the query strings just
could get rather big.

------
carsongross
I prefer REST for mainly aesthetic reasons: the URLs are pretty, and in Rails
I can handle different HTTP actions in the same method, which usually ends up
being some clean code:

    
    
      def index
        if request.put?
          update_stuff
        end
        # get/put render same response content
      end 
    

One of the unexpected benefits of intercooler.js has been that I can use REST-
fully designed end points for my html-partial endpoints, and it all just
"looks right", even though it isn't a traditional JSON API.

------
wampus
Is it correct to say that POST is not idempotent? Sometimes it is, and
sometimes it isn't. Maybe it would be more accurate to say there's no
guarantee that it's always idempotent.

~~~
bradleyankrom
POST is used to create resources that don't already have identifiers. So, if
you're repeatedly submitting that form, your request is creating distinct
resources on the other end. If the resource already exists -- if it has an
identifier -- you'd use (an unsafe, but idempotent) PUT to replace it.

------
donchipotle
This is purely focusing on it from the API level. REST is an architectural
style. This comparison seems like it is entirely missing the point.

------
joshguthrie
I prefer REST because one way fits all usages:

GET /resources, POST /resources, GET /resources/id, PUT /resources/id, DELETE
/resources/id

Five routes for one resource type. If you need more resources, you nest your
URIs. Why would you need POST /deleteResource?idRes=id when you can just
DELETE /resources/id?

Code reuse wins.

~~~
augustl
IMO the biggest challenge here is cases that doesn't fit in. What if you want
to create or update multiple records in a single operation, for example. There
are ways, namely additional batch resources, but structuring that is your
problem.

------
dimino
I would argue REST wins on beauty, because it continues to follow the intent
of a URL -- you can _locate_ the resource based on the URL. In RPC, the query
parameters break the URL concept a bit by including location data in the
parameters rather than in the path.

~~~
MichaelGG
Seems like you can easily convert, if you want positional parameters.
?id=1&foo=2 just becomes /1/2\. I fail to see how that really matters from the
final client or server code.

------
drawkbox
Many public apis are REST based but do have some RPC actions with url-based
HTTP APIs. Sometimes it isn't either or.

For example an API that allows you to get users might also have a job resource
or action to perform RPC jobs on the server from a manage api path or similar.

------
ianstallings
My honest feeling is that the argument is kind of moot because people will use
a combination of the two as necessary.

------
jtwebman
I think Rest works best in dynamically typed languages as it can be a little
less strict on format. I think in typed languages RPC could work out better as
you can filter out bad requests quicker with a stricter format. I also think
RPC tends to be more brittle to changes just like typed languages :)

------
fiatjaf
Because I can test and debug without requiring an enourmous environment set
up.

------
dedward
Because it's more straightforward.

------
dschiptsov
Isn't REST is a way to implement RPC?)

------
rando289
my god that site is unreadable grey on grey

