Table of contents
Basic components in gRPC
As with most interservice communications, gRPC supports the concept of clients and servers. There are no restrictions on the number of client/servers and how they are interconnected but the difference happens in the way they communicate with each other. Generally on a REST based implementation, the server (let’s say an API) would expose its API endpoints and the clients usually make a HTTP request to those endpoints. But in gRPC, the API would instead
- define all the contracts in a
protobuf
file (example.proto
) generate gRPC code
when the project is built (or an equivalent approach for dynamic languages)
Similarly, the client would define its own messages in a protobuf files. The client side protobuf files usually deal with preparing to send a message that the server understands, receiving a response and serialising/deserialising them etc which are all abstracted away, thanks to the protobuf layer. Finally, all the client needs to do is to call the relevent method on server to get a response.
As of this writing, there are a few experimental alternatives for protobuf in C#, such as using JSON Web APIs / HTTP REST endpoint style instead. More details can be found here
A sample proto file
Checkout a sample proto file that defines a contract for GreeterApi
that has one method titled SayHello
. This method takes in a HelloRequest
as parameter and responds with HelloReply
, both of which are again defined as messages in the file. When we build this code, it generates a gRPC code in the same language in which it is being built by default (or we can specify the language to build this to in options).
1
2
3
4
5
6
7
8
9
10
11
12
13
syntax = "proto3";
service GreeterApi {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
RPC Lifecycle
We saw how protobuf generates code for us, which is in turn used to communicate with client/server. But how does the client or server initiate the connection with each other? Normally for REST API requests in C#
, we can create a HttpClient
and use that to send/receive requests such as client.SendAsync()
. In gRPC it is slightly more complex than that:
- Create a channel
- This opens up the connection to the API / server
- Create a client
- This is the client that will call the RPC methods generated by gRPC
- This client can be reused and may need to be initialised only once during the lifecycle of the application
- Client sends a Request (with optional metadata), and server can send a metadata response
- This happens even before the actual request is processed by the server
- Useful in situations such as Authentication
- Once the server has processed the request, it sends back a response
Message Types
There are 4 types of messages that can be communicated with gRPC protocol:
- Unary (single request from client, single response from server)
- protobuf syntax:
rpc MethodName(RequestType) returns (ResponseType)
- protobuf syntax:
- Server Streaming RPC (single request from client, multiple responses from server)
- protobuf syntax:
rpc MethodName(RequestType) returns (stream ResponseType)
- Used in situations like video streaming where a client makes a single request, and server responds with buffered stream of video
- protobuf syntax:
- Client Streaming RPC (multiple requests from client, single request from server)
- protobuf syntax:
rpc MethodName(stream RequestType) returns (ResponseType)
- Used in situations such as client needing to send a multi-part upload to server
- protobuf syntax:
- Bi-directional Streaming (multiple requests from client and server, asynchronously)
- protobuf syntax:
rpc MethodName(stream RequestType) returns (stream ResponseType)
- More complex, suited for custom scenarios that require multiple asnchronous requests/response as a stream
- protobuf syntax:
Authentication options
Authentication here deals with how the client grpc authenticates and connects with the server, so do not confuse with general user authentication. gRPC again supports 5 types of authentication:
- Insecure authentication
- Really this should only be used in dev environments for testing purposes
- SSL/TLS
- This is the recommended level of authentication for gRPC
- Makes use of HTTP/2 connection by default when available
- Certificate is validated against the nominated trusted CA
- ALTS (Application Layer Transport Security)
- Specific for Google cloud platform (GCP)
- Google token-based
- This requires SSL/TLS to work, so an added layer of security when using Google token based authentication
- Custom
- gRPC also allows custom implementation of authentication, such as
OAUTH2.0
. - There are several packages that support custom implementations which can be found in gRPC’s website.
- gRPC also allows custom implementation of authentication, such as