restrpc

RPC vs restful endpoints


I've spent more time than I'd like to admit trying to understand the differences between RPC and restful endpoints. In fact, after going down this rabbit hole, I'm not even sure I fully understand what RPC is anymore. And I'm not alone. I see countless messages repeatedly asking for clarification.

Here's my understanding so far:

RPC and restful endpoints are largely conceptual in nature only. There are no standards.

Both are ways of invoking a function on a remote server.

In the case of restful endpoints, we map HTTP methods to CRUD operations on a resource.

In the case of RPC, we're concerned w/actions on an object.

However, in both cases, we're addressing remote method invocation.

I've read some folks say restful shouldn't be stateful and if it is, it's not restful. But aren't most restful endpoints using state via sessions? I mean, I'm not going to let just anyone delete data w/o being logged in.

And I've also read that functions like domain(.)com/login isn't restful b/c it's an action. This seems to make sense, but since I'm not writing my functions any differently on my server than I would a simple restful function, does it really matter what we call them -- restful vs. RPC.

I truly just don't understand what I'm missing and no posts thus far on StackOverflow appear to address this confusion.

Hoping someone can provide some insight using the above as a guide for understanding. Thanks in advance.


Solution

  • It's an amazing question. There is a huge difference between REST and RPC approaches, I'll try to explain it.

    RPC just lets you call some remote computer to make some job. It can be any job, and it can have any inputs and outputs. When you design API, you just define how to name this job operation and which inputs and outputs it will have.

    Step 1. Just RPC

    For example, you could have operation foo with one input and two outputs like that (I will use JSight API notation because it supports both RPC and REST API types):

    JSIGHT 0.3
    
    URL /rpc-api
      Protocol json-rpc-2.0
      Method foo
        Params
          {
            "input-1": 123 // some integer
          }
        Result
          {
            "output-1": 123, // some other integer
            "output-2": "some string"
          }
    

    When you design your RPC API you can use as many such operations as you want.

    So, what's the problem with this? Why do we need REST, if we already have RPC?

    The problems are the following:

    1. When you look at the method foo definition you do not have the slightest idea, what it does.
    2. When you design RPC APIs you have absolute freedom, but freedom often can be a bad thing. Because people think in different fashions. You could think, that your API is easy and elegant, but other people would not think so.

    Step 2. Standardized RPC

    If you are an experienced API designer and you use the RPC style, you will try to follow some pattern to avoid the two faults mentioned above. For example, let's imagine, that your foo method returns a customer entity. Then you will never call it like foo, you will call it getCustomer, like this:

    JSIGHT 0.3
    
    URL /rpc-api
      Protocol json-rpc-2.0
      Method getCustomer
        Params
          {
            "input-1": 123 // some integer
          }
        Result
          {
            "output-1": 123, // some other integer
            "output-2": "some string"
          }
    

    Ok! Now when you just look at this description, you can say, that this method returns a customer; that parameter input-1 is some filter, most possibly, ID; and output-1 and output-2 are some customer properties.

    Look, just using the standard way of naming the method, we made our API much more easy-to-understand.

    Still, why do we need REST? What's the problem here?

    The problem is, that when you have dozens of such RPC methods, your API looks messy. E. g.:

    JSIGHT 0.3
    
    URL /rpc-api
      Protocol json-rpc-2.0
      Method getCustomer
      Method updateCustomer
      Method getCustomerFriends
      Method getCustomerFather
      Method askCustomerConfirmation
      # etc...
    

    Why it is not easy to understand this bunch of methods? Because it is not the way our brain works. Our brain always groups actions by entity. You naturally think about an entity, and then about actions, you can do with it. E. g. what you can do with a cup? Take, hide, break, wash, turn over. And brain rarely thinks firstly about actions and then about entities. What can I take? Cup, ball, ice cream, ticket, wife. Not very natural.

    So, what is REST about?

    Step 3. REST

    REST is about grouping entities and defining the most standard actions with these entities.

    In IT we usually create, read, write, or delete entities. That's why we have POST, GET, PUT, and DELETE methods in HTTP, which is de facto the only implementation of the REST style.

    When we group our methods by entities, our API becomes much clearer. Look:

    JSIGHT 0.3
    
    GET  /customer/{id}
    PUT  /customer/{id}
    GET  /customer/{id}/friends
    GET  /customer/{id}/father
    POST /customer/{id}/ask-confirmation
    

    It is much easier to perceive now than in the RPC-style example above.

    Conclusion

    There are a lot of other issues, concerning differences between RPC and REST. REST has its faults as well as RPC. But I wanted to explain to you the main idea:

    REST is a standard, that helps you to organize your API in a user-friendly fashion, that is comfortable for the human brain, so any developer can quickly capture your API structure.

    RPC is just a way of calling remote operations.

    All the examples above are gathered here: https://editor.jsight.io/r/g6XJwjV/1