Remote Procedure Call (RPC) is a powerful technique for constructing distributed, client-server based applications. It is based on extending the conventional local procedure calling so that the called procedure need not exist in the same address space as the calling procedure.
What is gRPC?
gRPC is a modern open source high performance RPC framework developed by Google and Introduced in 2015 that can run in any environment and communicate to any service in any supported language. It used by many major Internet Companies such as Google, Netflix, Cisco, CoreOS, Juniper etc.
gRPC uses Protocol Buffers as it's Interface Definition Language.
Let's get started!
I came upon a problem in my work where I was required to use gRPC with Scala. Being a Software Developer, I knew how to do it in Java very well, but for some engineering reasons I was asked to write the same in Scala. Scala being a JVM language makes it very easy to write very efficient code in a very short footprint. The work that takes 500 lines of code in Java can be done easily in less than 100 lines in Scala. Due to lack of documentation from ScalaPB on Streaming Calls, I decided to write my on article on this.
Prerequisites
Basic knowledge of Scala
An empty scala project set up with ScalaPB and SBT
HelloRequest - Message to be sent as request to the server
HelloResponse - Message to be sent as Response to the client
HelloWorld - gRPC service containing different methods:
sayHello - Unary Call
clientStream - Client Side Streaming
serverStream - Server Side Streaming
streamHello - Bi-Directional Streaming
Implementing the service - HelloWorld
Create a new file HelloService.scala in src/main/scala/[your package]/ with the below content:
packagein.pbehre.scalaimportin.pbehre.proto.HelloWorldProto._
importio.grpc.stub.StreamObserver
importscala.concurrent.Future
class HelloService extends HelloWorldGrpc .HelloWorld {//Service to implement calls}
This is the basic service structure, needs to extend the HelloWorldGrpc.HelloWorld Base Implementation Class. Let's go ahead and override the methods
Unary Call - sayHello
This call takes a single HelloRequest Object and Returns a Future with HelloResponse Object.
overridedef sayHello(request: HelloRequest): Future[HelloResponse]={val name :String= request.name
val reply = HelloResponse(welcomeMessage ="Welcome, "+ name) Future.successful(reply)}
Client Side Streaming - clientStream
This will take a stream of objects from the client in a request observer, and then return them back to the client once the stream is end/committed in a single HelloResponse Object. Only one request session is used to stream content to the server.
Will take a single request HelloRequest object which will establish the request and thanks to http2.0, the grpc function will return a multiple stream of HelloResponse object in the same request.