A few weeks ago I’ve seen an interesting flock of tweets initiated by this question:

This question and the tweets that followed put my brain on quite an animated discussion…

voices-inside-my-head

After this internal discussion, I realized that this question (and all the tweet debate that follows it) could help me highlight a dark corner of my librainry: why should I considered REST’s request style (resource oriented) better than RPC’s (operation oriented)? Is RPC’s request style so evil? Is REST’s the panacea?

What RPC’s and REST’s requests styles look like

Before comparing the two request styles let’s see what they look like.

The HTTP request

Both RPC and REST use HTTP protocol which is a request/response protocol.

A basic HTTP request consists of:

  • A verb (or method)
  • A resource (or endpoint)

Each HTTP verb:

  • Has a meaning
  • Is idempotent or not: A request method is considered “idempotent” if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request (see RFC7231: Idempotent methods).
  • Is safe or not: Request methods are considered “safe” if their defined semantics are essentially read-only (see RFC7231: Safe methods).
  • Is cacheable or not
Verb Meaning  Idempotent   Safe   Cacheable 
GET Reads a resource Yes Yes Yes
POST Creates a resource or triggers a data-handling process No No Only cacheable if response contains explicit freshness information
PUT Fully updates (replaces) an existing resource or create a resource Yes No No
PATCH Partially updates a resources No No Only cacheable if response contains explicit freshness information
DELETE Deletes a resource Yes No No

The table above shows only the HTTP verbs used commonly by RPC and REST APIs.

RPC: The operation request style

The RPC acronym has many meanings and Remote Procedure Call has many forms.
In this post, when I talk about RPC I talk about WYGOPIAO: What You GET Or POST Is An Operation.

With this type of RPC, you expose operations to manipulate data through HTTP as a transport protocol.

As far as I know, there are no particular rules for this style but generally:

  • The endpoint contains the name of the operation you want to invoke.
  • This type of API generally only uses GET and POST HTTP verbs.
GET /someoperation?data=anId

POST /anotheroperation
{
  "data":"anId"; 
  "anotherdata":"another value"
}

How do people choose between GET and POST?

  • For those who care a little about HTTP protocol this type of API tends to use GET for operations that don’t modify anything and POST for other cases.
  • For those who don’t care much about HTTP protocol, this type of API tends to use GET for operations that don’t need too much parameters and POST for other cases.
  • Those who really don’t care or who don’t even think about it choose between GET and POST on a random basis or always use POST.

REST: The resource request style

I will not explain in detail what REST is, you can read Roy Fielding’s dissertation and The REST cookbook for more details.

To make it short and focus on the matter of this post, with a REST API you expose data as resources that you manipulate through HTTP protocol using the right HTTP verb :

GET /someresources/anId

PUT /someresources/anId
{"anotherdata":"another value"}

Examples

Here are some of my CarBoN API requests presented in RPC and REST ways:

Operation RPC (operation) REST (resource)
Signup POST /signup POST /persons
Resign POST /resign DELETE /persons/1234
Read a person GET /readPerson?personid=1234 GET /persons/1234
Read a person’s items list GET /readUsersItemsList?userid=1234 GET /persons/1234/items
Add an item to a person’s list POST /addItemToUsersItemsList POST /persons/1234/items
Update an item POST /modifyItem PUT /items/456
Delete an item POST /removeItem?itemId=456 DELETE /items/456

Comparing RPC’s and REST’s requests styles

I’ve selected some items to compare RPC’s and REST’s requests styles:

  • Beauty
  • Designability
  • API definition language
  • Predictability and semantic
  • Hypermediability
  • Cacheability
  • Usability

Beauty

Even if this item is irrelevant, as beauty is in the eye of the beholder, both styles can produce beautiful API as they can produce ugly ones.

Operation RPC REST
Read a person pretty version GET /readPerson?personid=1234 GET /persons/1234
Read a person ugly version GET /rdXbzv01?i=1234 GET /xbzv01/1234

So that’s a draw for this one.

Designability

Is it easier to design RPC ou REST endpoints?

Designing a RPC API may seem easier:

  • when you have to deal with an existing system as it is generally operation oriented but you’ll have to simplify and clean this vision to expose it.
  • when you deal mainly with processes and operations (as transform them into REST resources is not always trivial).

The design of an RPC API needs the designers to be strict to achieve a consistant API as you do not really have constraints.

Designing a REST API may seem easier when you deal mainly with data.

But even if in some certain case , designing a REST API seems a little harder than an RPC one, it gives you a frame that let you achieve more easily a consistent API.

And in both case you’ll have to deal with naming consistency.

Both style have pros and cons depending on the context but I don’t find that one style is more easier to design than the other. As I don’t really see a winner, that’s another draw.

API definition languages

You can perfectly describe both styles with API definition languages like Swagger, RAML or blueprint.

So that’s a draw, again.

Predictability and semantic

With RPC the semantic relies (mostly) on the endpoint and there are no global shared understanding of its meaning.
For example, to delete an item you could have:

  • GET (or POST) /deleteItem?itemId=456
  • GET (or POST) /removeIt?itemId=456
  • GET (or POST) /trash?itemId=456

To resign from the service you could have:

  • POST (or GET) /resign
  • POST (or GET) /goodbye
  • POST (or GET) /seeya

With RPC you rely on your human interpretation of the endpoint’s meaning to understand what it does but you can therefore have a fine human readable description of what is happening when you call this endpoint.

With REST the semantic relies (mostly) on the HTTP verb. The verb’s semantic is globally shared. The only way to delete an item is:

  • DELETE /items/456

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

  • DELETE /users/1234

REST is more predictable than RPC as it relies on the shared semantic of HTTP verbs. You don’t know what happen exactly but you have a general idea of what you do.

REST wins (but shortly).

Hypermediability

In both style you end making HTTP request, so there is no problem do design an hypermedia API with any of these styles.

This is a draw.

Cacheability

I’ve often seen (http) caching used as a killer reason to choose REST over RPC.
But after reading HTTP RFCs, I do not agree with this argument (maybe I missed something).
Of course if your RPC API only use POST for all requests, caching may be a little tricky to handle (but not impossible).
If you use GET and POST wisely, your RPC API will be able to obtain the same level of cacheability as a REST API.

This is a draw.

Usability

From a developer point of view both styles are using HTTP protocol so there’s basically no difference between RPC and REST request.
No difference on the documentation (machine of human readable) level too.

This is a draw.

Totalling points

Item Who wins?
Beauty Draw
Designability Draw
API definition language Draw
Predictability and semantic REST
Hypermediability Draw
Cachability Draw
Usability Draw

Do REST really wins?

REST wins thanks to the predictability and semantic item.
So, is the resource approach better than the operation one?

No.

RPC and REST are only different approaches with pros and cons and both are valueable depending on the context. You can even mix these two approaches in a single API.

The context, that’s the key. There are no panacea solution, don’t follow fashion blindly, you always have to think within a context and must be pragmatic when choosing a solution.

At least, I know now why I like the resource approach: its predictability and the frame given by the full use of HTTP protocol. What about you?

One last word to leave you with food for thought: in this time of advent of functionnal programming, having operation request style could make sense…

  • Pingback: Do you really know why you prefer REST over RPC? http://apihandyman.io/do-you-really-know-why-you-prefer-rest-over-rpc/ via @apihandyman()

  • The best experiences are rarely measured in extremes. IMO the best API designs incorporate a balance of REST + RPC semantics, where the usage is most appropriate. Resource-oriented design provides a big benefit in many categories, until it doesn’t. If the use case calls for it, RPC, or RPC sub-resources (under a REST collection) works out quite nicely.

  • alphazero

    The difference between RPC and REST, in principle, is the distinction between Interfaces and Resources. Your examples are REST-ish, not REST.

    Your browser is a REST client. You, the user, are one of the active components of this client making sense of the responses. (For example, a new link showing up on google.com is not going to end your browsing experience.)

    An RPC client is any peer end point that must know the remote interface of the remote peer. If your remote peer’s end point interface changes (c.f. new link on Google.com) it will break the client.

    • I don’t get why the “REST-ish and not REST”, do you mean REST-ish and not RPC?
      If that’s the case, you’re right in the strict sense of RPC which may not be the best word to describe the “operation approach” I’m talking about in this post (so many people call that, maybe wrongly, RPC though).
      I think I’ll edit the post later to summarize discussions I had on this “wording matter”.

      • Rjain

        The examples you have chosen are CRUDish (get one, get all, delete this, change that, etc.) and do not represent actions needed in real life application such as Approve, Reject, Escalate, Check-in, Search etc. REST loses on beauty (simplicity, intuitiveness) when you consider these examples.

        One reason why many people hate REST in business applications is due to close coupling with HTTP verbs which is arbitrary in non-CRUD situation and is not worth an extra minute of deliberation when your API has a single client (or two if you count the mobile version of app).

        • Approve, Reject, Escalate, Check-in, and Search are used in 1% of implementations. That is what you call biased data, Mr. Handman.

          • Rjain

            What about Play, Pause, Stop, Rewind. Or Reply, Forward, Recall. English has 100,000+ verbs. Should we have a dictionary of English verbs to REST HTTP verbs?

        • I don’t agree that the examples above are actions that don’t fit well into REST.

          Approve what? Reject what? Escalate what? Check-in what? Search for what? All of these things are related to some resource. If we can re-orient our thinking to the resources, we’ll see that all these things fit neatly into REST when we start to think “resource-first”.

          Just to take two examples, “Escalate” (for some issue that needs escalation) might be represented in REST as…
          PATCH /issues/249
          Body: {escalated: true}

          “Reject” (for some kind of approval request) might be represented in REST as:
          DELETE /expense-claims/579376/approval-request

          • Rjain

            Isn’t problem obvious with your suggestions for implementing Escalate and Reject actions? You cooked PATCH for one and DELETE for another. Some one else will cook it differently. Two cooks will fight over which is better recipe for Approve, Escalate and Reject. I never have to think about this sh*t in RPC style calls.

          • deviantmk

            Nooooooo

            Why would you use DELETE when you update the status of the resource :(
            Just use PATCH
            PATCH /expense-claims/579376/approval
            Body: {approve: false}

            The PATCH method is the correct choice here as you’re updating an existing resource

            Rest is just endpoints that need to be called or fed with data, stop over complicating things, EDUCATE YOUR SELVES AND CONFUSION WILL BE REDUCED
            and the guy below is full of nonsense

          • deviantmk

            I mean this nonsense guy @Rjain

          • Rjain

            Once you remove the (RESTy) colored glasses and see the light of the day, an endpoint fashioned like:
            base/{name-space}/call-it-what-it-does GET/POST with appropriate payload-in and response-out gives full toolset for remote service calls without the representational state transfer baggage tightly bound to underlying transfer protocol (that is monstrosities like patch and thatch).

  • Pedro

    While CRUD and HTTP Verbs do seem to match quite nicely, that is not always the case, and you frequently find that they do not.

    In the end, the usage of HTTP Verbs becomes pretty arbitrary and a pain in the ass. For most people however, it is only an implementation detail behind a library and therefore not a big deal, so quite frankly I see no reason for “hating” one approach or the other.

    Designing API’s is quite hard, after all.

    Ta,
    Pedro

    • The point is to be pragmatic and always consider the context.
      Concerning the “hating” part, you’ll have to the read twittter discussion that follow Camille’s tweet or ask Camille to find :-)

  • Robert Thille

    I would say that you should never use the GET verb for write-type RPC actions. We had a web app on our intranet which did so, and then we installed a web-crawler to index and make searching easy…
    We had to restore from backups as the crawler hit all the ‘delete’ links with GETs and the app took the action.

    • I had seen such thing (delete with GET) but fortunately do not experienced the web-crawler triggering it. That’s a good example to keep in mind to not do that! Thanks for sharing.

    • GET should NEVER be used for write operations, as it exposes data and makes it EXTREMELY easy to manipulate… not that POST operations are super difficult, but it’s not like every john doe with a browser can start fiddling with the data with just a browser and a keen eye. This is just a security induced best practice.

      • Omnilord

        What are your thoughts on GET /user/1/salt as a means of getting a new salt? This is definitely going to be a write operation to the session, but you are certainly not posting data either.

        • Devon Jones

          GET should be idempotent such that if no other element of the system changes, repeated calls to a GET endpoint should always return the same value. RPC or REST, not doing so is one of those things that breaks assumptions for other members of the network. For example caching by a load balancer.

        • Antanas Končius

          this is tricky part. it SEEMS that it should be “get me a new salt” but in reality it should be similar to “generate me a new salt and return it to me”, so it should be definitely NOT GET method, most likely PUT. on the other hand, GET /user/1/salt should return existing salt, not generate new one.

  • Dildo Baggins

    If you’re building an interface for creating, reading, updating, deleting objects, use REST. If you’re creating an interface with multifaceted behavior at any given endpoint, don’t use REST.

    Period.

  • Gil Shotan

    Your analysis is missing a crucial point: the REST protocol conforms to a much narrower specification. This makes it possible to reason about the nature of an API call without understanding the semantics. For example, with the following API call:
    GET /deleteItem?itemId=456
    only a human can understand that it is a destructible operation. Whereas: DELETE /item/456 makes it very clear. Aside from making the nature of the operation (safe, nilpotent, idempotent) to human readers, the real advantage with REST is that it makes the nature of the operation very clear to computer programs. Webcrawlers rely on this distinction, so If you had the following link /deleteItem?itemId=456 you can be sure that Google will delete all your users as it crawls your webpage.

    In general, it is a good idea to adhere to stricter protocols when you can. IP/TCP has some limitations as well, and its not good for everything, but having a clear and consistent API enables lots of developers to build on top of it applications that the original authors never imagined. Same goes with REST. If there will be a wide adoption of REST protocol one could imagine people doing crazy things like an automated API browser. And if developers find new ways to make REST protocols, say, faster and more efficient, then everyone who conforms to REST can benefit for free.
    My advice: start with REST and stick to it until you really can’t avoid it and need something more customized.

    • Thanks, your advice should be carved on tablets of stone. So many people are afraid to do “unrestful” things but sometimes it make sense.
      I should have split the predictability and semantic section in two parts (human and machine). Sometimes with REST the exact meaning of what is happening (beyond the HTTP verb) could be obscure, maybe that’s the point where you should start using custom things.

  • Good read, I’m glad that you didn’t pick sides with beauty!

    I think you undervalued predictability and standardization, IMO they are probably the reason why REST is generally preferred and closely tie into usability. Yes, both REST and RPC can use HTTP, but the meaningful inclusion of HTTP verbage makes REST easier to use. With REST composing routes is so intuitive once you’re familiar with the resources and it’s easy to predict if you’re getting back a single resource or a collection (if a route ends in an ID the result is a single resource, if not, it’s a collection); with RPC you rely on good naming alone.

    Treating actions as resources adds the nice side effect of being able to trigger them asynchronously and then poll their progress with a GET. You can do it with RPC too, but this functionality is more natural with REST (for me anyways).

    PATCH should be an idempotent operation.

    Cheers and thanks for the article :)!

    • Thanks for your comment.
      The problem is that nowadays, it seems that many people “choose” a REST approach by default without thinking about it, without analyzing if that fit for their needs. These people then tend to be very rigid trying to do all things in a REST way and did not see that they can use both styles.
      By the way PATCH is not idempotent (I was a surprised by that), here’s what says the RFC 5789 on that: “PATCH is neither safe nor idempotent as defined by [RFC2616], Section 9.1.”.

      • PATCH is especially not idempotent with JSON Patch (RFC6902), as it’s an ordered set of operations.
        JSON Merge Patch (RFC7386) could be implemented with idempotence, but as Arnoud points out, PATCH as a verb in HTTP is not considered idempotent.

        • Thanks for teaching me about PATCH, I had no idea that anything besides Merge Patch existed. PATCH as described in RFC 5789 is a scary and shitty operation that can do anything; it can create, delete and update any resource including itself. JSON Patch and JSON Merge Patch are great examples to show how broad PATCH really is. Thanks for them! I feel that Merge Patch should have it’s own separate verb (MERGE?).

          • It is interesting to see the development of PATCH moving towards media types, rather than additional verbs. When you look at the hypermedia space, media types are where all the big development is happening. It’s definitely a transition towards keeping simple verbs, and keep the nuances in the media types.

    • Josh B

      +1 for REST having an advantage for being more stricter and more standardized. One of the huge benefits of REST is that it is, in general, always the same and the scope of what happens is fairly specified. This means that a front end team and a back end can each build with the same assumptions of how the API will work. By standardizing on REST, you can take benefit of a lot of third-party libraries more easily. It can also be easier for teams who have to work with multiple API’s.

      You can have that with RPC too, but you have to work harder for it. Also, not everything fits nicely into the REST paradigm. REST works very well for transferring data objects, but it’s not so great for complex interactions.

      In general I think the real takeaway here is that RPC should not be viewed as something that is inherently bad. There’s lots of things that it’s very good for. Conversely, REST was designed to solve a specific problem that RPC does not handle well. There’s definitely a use and a place for both

  • Miguel Moquillon

    For me, the best approach is … POO as coined by Alan Kay (and thus as not commonly practiced in software engineering). If we applied this approach, the endpoints identifies an object and the HTTP is the transport protocol for messaging between them. The message identifier (or name) is passed in the HTTP header and the HTTP method carries the semantic of the message:
    – OPTIONS to know the messages understood by the object
    – GET to request an information
    – POST to trigger an operation in the behalf of the object (doesn’t ask information from an object to perform a task, ask to the object to perform itself the task)
    – PUT to add or update information (we don’t push its new state as it is the responsibility of the object (id est local retention))
    – DELETE to remove or erase information from the object (or the object itself from the system)

    • I suppose you meant OOP (Object Oriented Programming).
      Here’s an interesting comparing OOP and REST by Mike Amundsen http://www.devx.com/enterprise/the-vision-of-kay-and-fielding-growable-systems-that-last-for-decades.html

      • Miguel Moquillon

        Yes, I mean OOP.
        Interesting article.

      • Dao Shen

        Mike’s analysis in that article is fantastic, but Fielding’s initial solution (LWP) is muddled at best. In particular i am not at all a fan of the name/value pairs in the message and that fragile object is still embedded in there. The hints to other resources are good — we expect Fielding to get that part right. :)

        Following Amundsen’s work, i like a great deal of what he is trying to lead us to. I have implemented a number of message based architectures in the past myself to lesser and greater success (pre and post REST). They do work well with objects and objected oriented analysis. Additional domain analysis (in particular understanding context — kudos for catching that Mr. Handyman) also helps. If the messages at the boundaries of the systems are subsequently well crafted the resulting systems are less fragile, less coupled, and generally easier to reason about and to change.

        Message oriented systems (and for similar reasons systems written in a purely functional style) however suffer from other problems. State cannot be wished away. It will exist either explicitly or implicitly across our systems. As others have mentioned, doing the analysis to handle this is hard work.

  • Thanks for this really great article. I very much agree with your analysis.

    Another reason why I tend to favor the RPC style over the RESTful style is what I call “static paths”. I think most HTTP routers are too much complex, because we want to use “pretty” URLs like /customers/4213/invoices instead of /customerInvoices?id=4213. In order to match the pretty URL, which is a “dynamic path”, we need to use regular expressions or a trie (also called a radix or prefix tree). In order to match the “static path”, we just need to lookup the path in a hash map. I think that the benefits in terms of simplicity should not be underestimated.

    To be honest, static paths can be used as well in the RPC style or the RESTful style, but I think they feel more “natural” in the former.

    Considering that most APIs are called by programs, and that their URLs don’t appear in the web browser navigation bar, I think that presenting “pretty” URLs is less important than before, and that the simplicity of static paths is welcomed.

    There is an interesting answer on the same topic in gRPC’s FAQ:
    http://www.grpc.io/faq/

  • lesto

    What if you can get/delete using differenti parameter than the ID? The RPC is winner ad you can nane the parameters, with REST i nave no idea to male it clean

    • I’m not quite sure to understand the question but with REST deleting a resource is straight forward: DELETE /resources/{resourceId} for example: DELETE /items/456 will delete the item with id=456. And to get it you do GET /items/456.

      • Antanas Končius

        he/she meant “what if I want to delete some resources not by id, but other field”, for example how to delete user by name, not integer id, then resource identification doesn’t fit into standart pattern , kind of DELETE /users/13 . in lesto’s case it would be something like DELETE /users/?filter[name]=yada

  • Dave G

    I could be wrong but usually I hear RPC in reference to the SOAP based web services that became popular when .Net was pushing them. SOAP is very bloated and did not work well with non-Microsoft technologies and RESTful quickly surpassed as the API of choice.

    • SOAP is a kind of RPC, it’s working “very well” with non-microsoft technologies (used it with Java for years (please keep that between us ;-) ).
      The RPC I talk about is “not so RPC”, the point is more uniform vs non-uniform interfaces (thanks goes to Darrel Miller @darrel_miller for having explaining the matter like this).

  • Pingback: This week in API land, 7th edition | Restlet - We Know About APIs()

  • Pingback: RPC and REST: both are valuable depending on the context. Once again there is no silver bullet, one size doesn't fit all. http://apihandyman.io/do-you-really-know-why-you-prefer-rest-over-rpc/()

  • Devon Jones

    A point about accuracy: RPC doesn’t imply HTTP. RPC has existed for a long time in many forms. CORBA, DCOM, Thrift, Avro, Protobuffs, SOAP. There are many many forms of RPC and only a fraction use HTTP as a transport mechanisim (such as SOAP).

    I think you miss a huge set of points in this as a discussion, but probably the single biggest one is that a resource oriented interface provides documents that can be used, using a set of standardized semantics (http headers, standardized methods, etc) that are encoded into a huge part of the architecture of the rest of the internet. A properly designed RESTful interface should seamlessly worth with load balancers, caching, proxies, etc. With RPC, it’s a crap shoot, and the details vary with. every. single. implementation.

    RPC is that, it’s a Procedure call. What this means is that your app that is calling the procedure is intimately coupled with the internals of the implementation. By publishing documents, a RESTful interface is making few assumptions about it’s usage, resulting in a lower likelihood of breakage as that service is modified in the future. RPC based distributed systems are fundamentally more brittle over the life of the system because what’s being exposed is a set of procedures, implicitly coupling the client with the logic of the service.

    A couple articles that are worth reading:
    http://duncan-cragg.org/blog/post/strest-service-trampled-rest-will-break-web-20/
    http://harmful.cat-v.org/software/xml/soap/simple

    • Devon,

      The article is about RPC in the context of HTTP, not RPC in general.

      You can do RPC over HTTP in a way that still benefits from load balancers, caching, proxies, etc. The trick is that URLs designate operations instead of resources.

      You’re assuming that coupling through operations (with RPC) is worse than coupling through data/representation (with REST). It’s an old debate in computer science and to my knowledge the answer is not clear cut. It depends a lot on the problem at hand. Both approaches have their pros and cons.

      In my opinion, the real power of REST is in the hypermedia, which is great when an interactive user wants to navigate in the API. But it’s less useful for an automated client, which probably explains why most APIs are not really RESTful (according to Fielding’s definition).

      • Devon Jones

        Fair enough on the HTTP part. As for the coupling via data or coupling via operations, I’m a UNIX guy, and at least within that paradigm, the answer is pretty clear. The majority of UNIX as a problem solving tool is piping representation between operation agnostic tools. I would argue that this has created a far far less fragile and far more flexible environment for solving problems.

        Coupling via operation is brittle and rigid.
        Coupling via representation requires a lot of extra parsing code, and can break when representations change.

        My experience is that the tradeoffs of coupling via representation are far more palatable.

        • I don’t think your analogy between REST and piping really works.

          1/ Most REST APIs are used in a request-response style. There is no multi-stage piping. You just have one client that requests a resource on a server.

          2/ In the piping paradigm, the set of available commands is very large. It is not limited to the set of HTTP methods. I think the operations are very important in the piping paradigm.

          • Devon Jones

            That’s not the connection I’m referring to, what I mean is that when using rest, you give me a document, and I’m free to parse or use that document however I like. Just as when piping between commands, the representation is the contract. You expressly pointed out that “You’re assuming that coupling through operations (with RPC) is worse than coupling through data/representation (with REST).”. I’m responding to that by pointing out that making the representation your contract instead of operations is akin to operating purely on the text output from one command as the input to the next. wc doesn’t care about the operations before or after it, it only cares about the text and it’s own flags. It’s completely neutral on what opera ions it’s interacting with, because it has a defined stdin/stdout contract. This is where REST is similar – the only thing that matters is the representation passed in or coming out, it’s operation and context neutral. In fact, I regularly do use rest calls in the middle of pipe chains because of this operation neutrality, something that’s not as easy with rpc, because with rpc, context generally matters.

            Approached another way: with rpc, you nearly always have to maintain state on both sides of the call (both server and client) to represent the status of the interaction between the systems. With a properly designed rest system, that state assumption is expressly severed.

  • Pingback: Links & Reads from 2015 Week 20 | Martin's Weekly Curations()

  • Pingback: API Digest #13()

  • REST works ok’ish as a client <=> server (RPC) protocol. Its abysmal as a middleware protocol because of Http (need to wait for response until next request can be sent on same connection or open myriads of connections losing request ordering). The popularity of REST IMHO is caused because its very easy to understand and a lack of understanding networking fundamentals. Using http as a middleware loses > factor of 10 compared to websocket or tcp based protocols.

    • Brian White

      Which patterns work best with Websockets?

      • Seb Schmidt

        Thats a good question. And I have few more.

        How do you implement batching of multiple api calls using REST?
        What are good patterns to make a REST-API (that depends on http verbs) non-blocking?

        RPC-Style API’s …
        – can be easily invoked by a blocking http client AND a non-blocking UDP-Client
        – can delegate responsibility to its clients to decide which network protocol fits the current context.

        I have some experience with JSON-RPC 2.0 (https://en.wikipedia.org/wiki/JSON-RPC).

        A major difference compared to REST is the request routing.
        – REST Routing : uri & http verb
        – JSON-RPC Routing: uri & rpc.method

        JSON-RPC …
        – is well documented
        – light weight compared to SOAP-RPC
        – uses JSON compared to SOAP, XML-RPC, …
        – supports batching of multiple api calls
        – does not depend on network protocol
        – enables clean & simple api design (CRUD and Non-CRUD)
        – supports schema-based request & response validation & endpoint description (e.g. json-schema)
        – but has its drawbacks as it comes to hyperlinking of resources

        Some RPC-Examples …

        This could be a non-blocking fire & forget api call via ZeroMQ-Messages …

        {
        “method”:”User.Friends.add”,
        “params”:{
        “userId”: 123,
        “items”: [
        {“name”:”King”},
        {“name”:”Kong”}
        ]
        }
        }

        Preferably this would be a blocking call, since the client requires the response …

        {
        “method”:”User.Friends.find”,
        “params”:{
        “userId”: 123,
        “filter”: {
        “name-eq” :”K*”,
        “created-gt”:”-2 hours”
        },
        “limit”: 1000,
        “offset”: 0
        }
        }

        And this could be a batched call …

        [
        {
        “method”:”User.Friends.add”,
        “params”:{
        “userId”: 123,
        “items”: [
        {“name”:”King”}
        ]
        }
        },
        {
        “method”:”User.Friends.find”,
        “params”:{
        “userId”: 123,
        “filter”: {
        “name-eq” :”K*”
        }
        }
        }
        ]

  • I can’t wrap my head around how you can call everything a “draw”, despite showing the obvious drawbacks of RPC.

    Is the only way to make REST ugly by pretending that somebody built an API where they called the Person record “xbzv01″? Really?

    Is RPC at its most beautiful a re-invention of HTTP’s verb, but in a nonstandard place? Really?

    To show off the “beauty” of the RPC style, I’ve put some custom text in the Website text field to tell you where the Title of my response is. Apparently that’s just as good as putting my Name in the Name field and my Website in the Website field.

  • Seb

    How about event driven architectures? How does REST fits into that world?
    I assume, there a quite lot of situations where our lovely REST religion finds its boundaries.
    Let’s think about WebSockets, PubSub, Messaging, Enterprise Event Bus, …

    Currently, I find google’s grpc quite interesting …

    “RPC framework that puts mobile and HTTP/2 first”

    http://www.grpc.io/docs/
    https://medium.com/@btaylor/react-with-c-building-the-quip-mac-and-windows-apps-c63155c1531b

  • Pingback: XML-RPC In A Nutshel | Hence A Hedgehog()

  • One of the major drawbacks I have experimented with REST is dealing with complex inputs. The beauty of the URLs and the resource oriented approach collapse. Imagine for example filtering a collection of resources by different categories, criteria, facets, page number, etc.
    This is one of the reasons that made me start working on https://github.com/brutusin/jsonsrv. Hopefully you find it interesting

  • Great post.
    My 2 cents: An important point worth mentioning are the semantics of error handling.
    Error handling is often a substantial part of our code.
    Because of the nature of REST it is very easy to interpret HTTP errors semantically: 404 – resource does not exist, 301 – moved, etc.
    By it’s nature, RPC requires that you understand what you are doing in order to handle errors correctly.

    • Good point, but RPC can be implemented on top of HTTP too, this way you can benefit from the semantics of both, not only for error handling but also for caching, revalidation, multipart requests (i use them to upload several files in the same JSON_RPC-over-HTTP request), safety, idempotence, ….

      • You are right – RPC can (and should) be implemented without breaking http standards.
        But I find that when implementing REST people tend to follow HTTP semantics more strictly.
        The “proprietary” nature of RPC APIs tends to lead people to misplaced “creativeness”.
        That is not due to any technical limitation – it is just an observation on behavior I’ve met in several projects.

  • I overall agree that RPC vs. REST is not a cage-match for the One True Approach(tm). However, I disagree that hypermedia-ability is a wash. For Hypermedia to even work, you need to have resources you’re hyperlinking to, and those resources need to have known semantics. If you’re linking to “I am a part of this collection” or “my owning user is this user”, then you need to have a URI that represents that collection or user. If you have a URi that represents that collection or user, then GETing it… had really better give you some kind of information about it because I’ve no idea what you’d do with it otherwise.

    In REST, your URIs represent NOUNS.

    In RPC, your URIs represent VERBS.

    A hypermedia link from noun to noun makes sense. A hypermedia link from verb to verb… I don’t even know what that means.

    If hypermedia links aren’t relevant to your use case, then that’s not relevant. But I don’t think it’s fair to say that hypermedia is a wash between REST and RPC generally. Hypermedia is particularly a REST/noun-based concept that has no meaning in an RPC/verb-based model.

  • Bob

    The actual semantics in the application layer never mattered to me. I prefer RPC because it’s called just like regular procedures/functions in code source and tends to be fast.

  • Katarzyna Siwek

    I am convinced to follow API Design Guidelines by Dix, Paul in “Service-Oriented Design with Ruby and Rails” (quote):
    – URIs should be descriptive
    – When possible, API endpoints should be exposed as resources
    – Data should be descriptive

  • Intresting discussion, but keep in mind that REST is bound to http. The tendency is now also to other protocols like websockets to get bidirectional communication. Rest is made with synchronous request response cycles.

  • Jeroen Keppens

    We use REST for most things that handle data: get an article, ge an overview of articles, modify an article, delete an article, etc… Commenting on an article, user registration falls under this (REST).

    What we use RPC for is state changes or actions on objects that we only allow partial changes (theoretically this is a patch, but we want to avoid checking that only specific fields are being patched).

    RPC (action) : GET /user/~/resendActivationMail (no update in db)
    RPC (action / patch) : POST /article/123456/approve (this could be a PATCH where we set “state” to published)

    REST => GET /article/123456/comments -> get comments for article 123456
    => example: one comment returned is comment 98765
    REST => DELETE /comments/98765 -> hard delete of a comment
    RPC => POST /comments/98765/approve -> approve a comment as administrator (instead of a patch with { “isApproved” => true, but let’s say we don’t allow any other part of the comment to be modified by the api consumer}

    What do you think?

    • Dao

      When you find yourself concerned with partial updates, specifically that you want to control what portions of a resource are being patched, you might consider creating resources that specifically update only those attributes. I am not looking at your domain, but in general this is a common scenario and indicates a need for more finely detailed resources (or messages about resources). You can do this RPC style or Resource style. After 30 some years i tend more towards either resource or message oriented styles, but only you can make that decision after understanding your domain. If the domain is simple enough sometimes a doThis() operation is all you need. It is as more systems (people and machines) interact that additional constructs are needed to deal with the complexity.

      In your example it seems you have already solved this. An “approval” endpoint would work just as well as the “approve” verb. The composition and interaction of the domain entities is more important than any question of REST vs RPC vs Other for an example this simple. I personally might go with the “approval” entity as that might stand up longer as the system changes, but the isolation of the approval context is what is most important from my point of view.