Procedure call - Simple function call in the same program on the same machine.
What if this function needs to be called from outside the host computer(server)? One of the options is to build an API.
If we are building API's using HTTP, we can go with one of the below two options.
RPC(remote procedure call) -
One program can request a service from another program located on a different computer without understanding the underlying network details. It’s a procedure call as if it’s on the same machine but it’s not on the same machine and the RPC library/framework takes care of abstracting all of that complexity.
- With REST, the client will have full access to HTTP via the HTTP client library (eg: python requests or nodejs axios). The client has to set the correct headers, set the message body, deal with serialization etc. Then there are vague and confusing RESTful/REST constraints as well like HATEOS, modelling the endpoints in certain way, etc. which becomes difficult to adhere to as the application grows.
Below example describes a client making API call to add a new book (CRUD oriented)
import requests
url = "https://www.myserver.com/api/v1/books"
body = {"book_name": "intro to c"}
x = requests.post(url, json = body)
- With RPC, the client simply calls a function (method exposed by RPC library) with required arguments as if it's a local function call. The RPC library will take care of the sending the data across the network.
Below example shows the same using RPC (Action oriented - notice the addBook() method)
import myCustomRPC as rpc
myRPC = rpc('www.myserver.com')
x = myRPC.addBook('intro to c')
RPC is a broad term that describes calling some functionality on a remote machine as if it's a local function call. There are many variants of RPC like XML-RPC, JSON-RPC, SOAP, HTTP RPC (used by slack API's), gRPC etc.
gRPC
Now if we decide to go with RPC for all our API's, we can use gRPC which is an RPC framework. In order to build gRPC service, we need to write a service definition file (protobuf definition) where services and methods are defined. Using the service definitions, we can automatically generate code (both client side and server side) in all major languages using protoc(+ gRPC plugin). The client-side code here contains methods that the API consumer can call.
gRPC supports four modes (unary, server stream, client stream, bi-directional) of communication out of the box (thanks to HTTP/2). gRPC also has pluggable features like authentication, lightweight serialization format like protobuf, tracing, client-side load balancing, health checking, timeouts etc.
"How does the transport layer work? If it's over the network?"
The API consumer or server don't have to deal with transport(HTTP or TCP) layer directly. gRPC client and server stubs abstract these details completely. Currently gRPC uses HTTP/2 over TCP and will support HTTP/3 over QUIC in the future.
Why use gRPC over REST?
gRPC is great for low latency services in the backend. Lot of popular applications now use gRPC heavily. For eg: Envoy proxy uses protobuf definitions and gRPC (for logging, discovery services, etc..)
Below from gRPC docs
Why is gRPC better/worse than REST?
gRPC largely follows HTTP
semantics over HTTP/2 but we explicitly allow for full-duplex
streaming. We diverge from typical REST conventions as we use static
paths for performance reasons during call dispatch as parsing call
parameters from paths, query parameters and payload body adds latency
and complexity. We have also formalized a set of errors that we
believe are more directly applicable to API use cases than the HTTP
status codes.
Why is gRPC better than any binary blob over HTTP/2?
This is largely what gRPC is on the wire. However gRPC is also a set
of libraries that will provide higher-level features consistently
across platforms that common HTTP libraries typically do not. Examples
of such features include:
- interaction with flow-control at the application layer
- cascading call-cancellation
- load balancing & failover