Quick Start

This guide gets you started with ZIO gRPC with a simple working example.

Prerequisites#

Get the example code#

The example code is part of the zio-grpc repository.

  1. Download the repo as a zip file and unzip it, or clone the repo:

    git clone https://github.com/scalapb/zio-grpc
  2. Change to the examples directory:

    cd zio-grpc/examples/helloworld

Run the example#

From the examples directory:

  1. Run the server:

    sbt "runMain zio_grpc.examples.helloworld.HelloWorldServer"
  2. From another terminal, run the client:

    sbt "runMain zio_grpc.examples.helloworld.HelloWorldClient"

Congratulations! You’ve just run a client-server application with ZIO gRPC.

Update a gRPC service#

In this section you’ll update the application by adding an extra server method. The gRPC service is defined using protocol buffers. To learn more about how to define a service in a .proto file see Basics Tutorial. For now, all you need to know is that both the server and the client stub have a SayHello() RPC method that takes a HelloRequest parameter from the client and returns a HelloReply from the server, and that the method is defined like this:

// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

Open src/main/protobuf/helloworld.proto and add a new SayHelloAgain() method with the same request and response types as SayHello().

// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
// Sends another greeting
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

Remember to save the file!

Update the app#

The next time we compile the app (using compile in sbt), ZIO gRPC will regenerate ZioHelloworld.scala which contains a trait with the service definition. The trait has an abstract method for which RPC method. Therefore, with the new method added to the trait, we expect the compilation of HelloWorldServer.scala to fail, since the method sayHelloAgain will be undefined.

Let's implement the new method in the server and call it from the client.

Update the server#

Open src/main/scala/zio_grpc/examples/helloworld/HelloWorldServer.scala, and add the following method to GreeterImpl:

def sayHelloAgain(request: HelloRequest) =
ZIO.succeed(HelloReply(s"Hello again, ${request.name}"))

Update the client#

Open src/main/scala/zio_grpc/examples/helloworld/HelloWorldClient.scala, and update the definition of the myAppLogic method in GreeterImpl:

def myAppLogic =
for {
r <- GreeterClient.sayHello(HelloRequest("World"))
_ <- putStrLn(r.message)
s <- GreeterClient.sayHelloAgain(HelloRequest("World"))
_ <- putStrLn(s.message)
} yield ()

Run the updated app#

If you still have the previous version of the server running, stop it by hitting Ctrl-C. Then run the server and client like you did before inside the examples directory:

  1. Run the server:

    sbt "runMain zio_grpc.examples.helloworld.HelloWorldServer"
  2. From another terminal, run the client:

    sbt "runMain zio_grpc.examples.helloworld.HelloWorldClient"

What's next#

note

This document, "ZIO gRPC: Quick Start", is a derivative of "gRPC – Quick Start" by gRPC Authors, used under CC-BY-4.0. "ZIO gRPC: Quick Start" is licensed under CC-BY-4.0 by Nadav Samet.