Skip to content

Instantly share code, notes, and snippets.

@kevinswiber
Last active April 11, 2021 16:50
Show Gist options
  • Save kevinswiber/8576d6083b0f8acece20 to your computer and use it in GitHub Desktop.
Save kevinswiber/8576d6083b0f8acece20 to your computer and use it in GitHub Desktop.
A brief moment of RPC vs. REST.

RPC vs REST

Here's a brief analysis of RPC vs. REST based on one person's opinion.

RPC

Note: It has been a long time since I've written a legit RPC system. Some of this experience may be based on currently outdated practices.

Contracts

Type and method signature contracts are shared between client and server. An Interface Definition Language (IDL) describes fields, types, and services/classes. Client code can be generated from this contract.

Example (from Thrift Tutorial):

service Calculator extends shared.SharedService {

   void ping(),

   i32 add(1:i32 num1, 2:i32 num2),

   i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),

   oneway void zip()

}

Benefits

  • Client libraries almost come for free due to code generation from contracts.
  • Types and methods signatures are reliable and have type guarantees. This means certain error detection can happen client-side.

Problems

  • Clients often try to hide the network. The network becomes the biggest risk, and when problems occur, errors often propagate oddly, offering little help toward a debugging effort.
  • When the type of a method parameter (e.g., id) changes from an int to a string, clients will start receiving type errors until their contract is updated. To get around this, sometimes developers just using string for all potentially volatile parameter types. This negates one of the benefits of using an RPC contract.
  • Can be difficult to scale depending on underlying protocol.
  • Revisions often require clients to adhere to a new contract.

REST (URL-based)

Contracts

URL-based REST contracts are tied to:

  • Host names
  • URL paths
  • URL query parameters
  • HTTP methods
  • HTTP headers
  • Request bodies
  • Response bodies

Example (from Apiary Tesla API):

## GET /vehicles/{id}/command/climate_state
Returns the current temperature and climate control state.
+ Parameters

    + id (number) ... The ID number of the car

+ Response 200 (application/json)

    + Body

            {
                "inside_temp": 17.0,          // degC inside car
                "outside_temp": 9.5,          // degC outside car or null
                "driver_temp_setting": 22.6,  // degC of driver temperature setpoint
                "passenger_temp_setting": 22.6, // degC of passenger temperature setpoint
                "is_auto_conditioning_on": false, // apparently even if on
                "is_front_defroster_on": null, // null or boolean as integer?
                "is_rear_defroster_on": false,
                "fan_status": 0               // fan speed 0-6 or null
            }

Benefits

  • Many benefits come from the underlying protocol (HTTP) in the way of scaling, caching, authorization, content negotiation, and a layered network architecture (allowing for proxies/gateways).
  • Clients are often forgiving if new fields emerge in responses or if existing fields change in a way that's resolvable by type coercion.

Problems

  • Clients often need to be built manually. Though some code generation tools exist, the differences between a local API and a network API can make the generated client libraries awkward.
  • Lack of clear advice on operation modeling. Sometimes you just need to turn off the damn coffee pot.
  • Revisions often require clients to adhere to a new contract.

REST (Hypermedia-based)

Contracts

Contracts are based on available features of the chosen hypermedia type.

This may include:

  • Data fields
  • Link relations
  • Action names
    • Field names
  • Class attributes

Example: Wurl Developer Site

Benefits

  • Same as REST (URL-based) Benefits above.
  • Self-describing with links and actions. Helpful when guiding clients on what to do next.
  • Can evolve by adding new link relations and actions.
  • Preferred approach when modeling operations. Easy to create a task-based interface.
  • Revisions often do not require clients to adhere to new contracts.

Problems

  • Lack of available tooling, small number of client implementations. All clients require manual effort.
  • Standards are still being defined, making it difficult to get started.
  • Can be heavier on data transfer size.
  • Lack of familiarity == Fear of the unknown. In other words, adoption can be difficult.

Conclusion

All the above approaches have their place in software and are neither good nor evil.

  • When working on small deployments of a self-contained distributed system, RPC may be the best option. Client code generation can be very powerful when needing to move fast. Just be sure you can effectively handle the network errors.

  • Choose a REST (URL-based) approach if you're looking for greater scale, caching, authorization, and the benefits of intermediaries (proxies/gateways). HTTP provides a lot of rich features over typical RPC approaches.

  • Choose a REST (Hypermedia-based) style if your contract is task- or workflow-based, has many clients you do not control, and you need the above-listed benefits of HTTP.

Errors / corrections? Hit me up: @kevinswiber

Feel free to comment below.

@earth2marsh
Copy link

rpc vs rest vs rest?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment