gRPC Implementation using Play framework (Scala)

Mohan Singh Bomrel
Grid Solutions
Published in
3 min readDec 8, 2021

--

gRPC is a Google-developed procedural framework that was first released in 2015. gRPC has gained increasing usage in recent years, based on the HTTP2 protocol for transmission and Protocol Buffer (Protobuf) as the interface specification language. Bidirectional streaming and efficient binary encoding are two features of gRPC that typical REST APIs don’t have.

In this article, I am going to write about how we have replaced REST with gRPC with play framework of version 2.7.x and 2.8.x.

Before jumping into the topic, I would like to describe the features of gRPC which made us switch from REST to gRPC. It is found that gRPC has an ability of 7 to 10 times faster message transmission than REST.

We have got four types of API in gRPC:

Let’s see the use case scenario of each type:
Unary RPC
A method that returns one response for one request. for e.g: General API, communication between applications.

Server streaming RPC
A method that responds to many requests with a single response.
e.g. When pushing multiple data from the server such as server-side push, timeline, feed delivery, etc.

Client streaming RPC
A method that returns one response to multiple requests. e.g. Large amount of data upload etc.

Bidirectional streaming RPC
A method that responds to multiple requests with various responses.
e.g. For two-way communication such as chat.

A simple example would be:

gRPC: An RPC API request might use POST /deleteItem and have a query string that says { “id”: 3 }
REST: A REST API request would write this request as DELETE /item/2.

Since the official website of gRPC(https://grpc.io/) doesn’t provide Scala Code Implementation, there is one plugin called ScalaPB, protocol buffer compiler (protoc) which is being used by ZIO, Cats Effect, and Akka.
In our play framework application, we are using play-grpc (https://github.com/playframework/play-grpc). play-grpc is built on top of akka-grpc (https://doc.akka.io/docs/akka-grpc/current/)

We have faced lots of library incompatibilities issues while implementing play -grpc in the play framework version 2.7.x. So, we need to exclude the libraries from it like the code which is given below.

"com.lightbend.play"    %%    "play-grpc-runtime"      % "0.9.1"               exclude("com.typesafe.play","play_2.12")
exclude("com.typesafe.play","play-akka-http-server_2.12") exclude("com.typesafe.akka", "akka-actor_2.12)
exclude("com.typesafe.akka", "akka-discovery_2.12"),

The play-grpc-scala examples simply include the application which doesn’t include any custom application loader. So, If you are using the custom GuiceLoaderApplication, the possible way to include the grpc clients in the application loader is:

import com.example.AkkaGrpcClientModuleinitialBuilder.bindings(new CustomModule(),new AkkaGrpcClientModule())

So, the application using play version 2.8.x has used macwire for dependency injection. Since the play-grpc v0.9.1 is targeted for 2.8.x, we don’t have any libraries mismatch problems. We should implement the following code so that the application can inject the AkkaGrpcClientModule.

implicit val grpcClientSettings: GrpcClientSettings = GrpcClientSettings.fromConfig("metadata.MetaDataService")
//Since other modules are wired using macwire, we need to implicitly define the GrpcClientSettings in Applciation Module defined using macwire

--

--