Testing gRPC #1: Set up a gRPC server and make an API call via gRPC UI

Gaurav Singh
7 min readFeb 17, 2024

--

Hi everyone,

I’ve been busy testing and automating some gRPC APIs at work for the past 6 months and I’ve found this technology fascinating.

While HTTP APIs are discussed extensively in blogs and conference talks, curiously gRPC is still a less talked about technology in the Quality engineering space. Let’s change that, shall we?

Why should you read this? ❓

In this blog series, we’ll take a deeper look at gRPC from the lens of a Software Engineer looking to test all the different aspects. If your org uses gRPC this may help solidify its concepts and help you to test better. If not, who knows you may come across this technology in the future and can come back to this series

What will we learn in this series?

  • gRPC concepts such as client stub, protocol buffers, blocking, and async calls
  • Set up a gRPC server and a client for an example service
  • How to do unit testing
  • How to do functional API testing
  • Performance test these APIs

By the end of this series, I want to personally have a deeper intuition of how to approach all testing at these different layers and take you along with me on this learning journey.

This will be a ton of fun 💖.

I hope you are as excited to start on this learning journey with me. 🏃

What is gRPC?

gRPC stands for Google Remote Procedure call, It is a modern framework to design APIs so that a client can call a method with some params on a remote server (running on a different machine) as if it were a local object.

gRPC uses protocol buffers to define the service and enable serialization/de-serialization. It is essentially an interface definition language (IDL) and we can generate client and server code in any supported language (C++, Java, Python… etc) using a proto compiler.

Source: Introduction to gRPC

Why gRPC?

  • Clients (stub) could call any method defined within a service
  • gRPC is language agnostic i.e. clients could be written in one language (Ruby, Java) and served in another one (C++)
  • gRPC allows for full duplex streaming i.e. client streaming, server streaming, or bi-directional streaming of messages such that clients and servers can issue read or write streams in any order.
  • It supports sync and async flows
  • Mobile Clients can use advanced streaming and connection features that help save bandwidth and make fewer TCP connections to save battery life and CPU usage
  • gRPC provides advanced load balancing and failover, cascading call cancellation, interaction with flow control at the application layer
  • Uses static paths in URLs for performance reasons and reducing the cost of parsing query, path, and payload body
  • Has formalized set of errors that are more directly applicable to APIs than HTTP status code

If you prefer watching a video, you can watch from ByteByteGo for a quick overview or from IBM Cloud

Protocol buffers

Protocol Buffers (protobufs) are used as the IDL (Interface definition language) to define the gRPC service, essentially this means we can define what methods would this server/API expose along with what params would be passed in, and what response would be returned.

Protobufs are also used as the message exchange format to define the request/response formats and then using a proto compiler (protoc), we can generate client and server code in the supported languages.

What are some advantages of using protocol buffers?

How are protocol buffers used?

Source: How do protocol buffers work

For example: below Person.proto generates below Java class Person.java

To generate client and server code using protoc (protocol buffer compiler), Please read grpc-java/README.md at master

Setup

Now that we have some idea about gRPC and protocol buffers (at least conceptually), let’s get our hands dirty 🤝 and set up a gRPC server and client for an example service to see how these work practically

We will use the Java programming language and I’ll be using Java 17 in this example, we will follow the official gRPC tutorial to set up this app with the client and server

The service that we will set up is called the route guide. You can find the code for that in /grpc/examples/routeguide, we will understand the methods it offers as we set it up.

Let’s clone the code using the below

Note:

We use the v1.61.0 branch by specifying -b in the clone command and -depth to do a shallow clone and only get the latest commit. This is to ensure we don't pull in all the git history

We will change the directory to

Defining service and request, response in proto file

The service request and response types are specified in the proto file https://github.com/grpc/grpc-java/blob/v1.61.x/examples/src/main/proto/route_guide.proto

To see the service definition, its methods, and request responses, let’s look at the service RouteGuide

We can see that this service offers 4 different methods

  • GetFeature
  • ListFeatures
  • RecordRoute
  • RouteChat.

Each of these provides an example of a different type of RPC call that we can make (simple, server side streaming, client side streaming, bidirectional streaming).

We will grasp them when we test these methods, but for now, you can see that each method accepts a proto and returns either a single proto or a stream of protos (array of protos)

If we look further down in the proto file, we can see how these protos are defined.

  • Each proto starts with a keyword message
  • We specify fields with their appropriate data types like int32, string, or repeated (similar to an array)
  • Proto can have other proto messages as its member fields to create a rich representation of data

Generate server and client code

Given the above service definition, we usually generate client and server interfaces using proto proto-compiler

In the above repo, we can use Gradle to generate these Java classes. You can find these instructions at https://github.com/grpc/grpc-java/blob/master/README.md

We need to ensure the below dependencies are added to our build.gradle file

We need to have below config in our build.gradle file to allow generation of client and server interfaces

Note: grpc-java adds config to support both Android and non-android projects and thus the config is slightly more complex. You can see it here

To ensure latest classes are generated, we should run:

cd examples

Running server with reflection and seeing APIs with gRPC UI

And to run the server, run below:

We can now see that we have the server running on localhost:8980

Let’s play with these APIs using a command line utility called grpcui, to install it run below on macOS:

Once installed, we can spin up the web app to inspect our gRPC APIs using below:

When you initially run this, You will see an error message like below, Oh.. no… 🤦

What went wrong here?

The message is pretty self-explanatory.

To play around with APIs with GRPC Web UI you need to enable server reflection support, If curious, read this tutorial to enable this for the server and understand this in detail

But in short, we need to add package import below and add ProtoReflectionService to our serverBuilder in examples/src/main/java/io/grpc/examples/routeguide/RouteGuideServer.java

After making this change, we can again build and run the server as above and start the grpcui

We can see that the gRPC UI is up and running. We can see our 4 service methods being available

We can select the method that we want to test and then select a request payload and call that API directly

Let’s say we want to call GetFeature method with a test latitude and longitude

We can enter a test latitude and longitude in Request Form

Or directly update the request JSON in Raw Request

For example, say we want to check any feature at given lat or long

If there is no feature at the specified location then the API returns an empty name, like below:

Congratulations! 🎀 You’ve made your first gRPC API request.

In the follow-up post, we will understand other methods for this API and also understand what a unit test for these API methods looks like

Thanks for the time you spent reading this 🙌. If you found this post helpful, please share it with your friends and follow me (@automationhacks) for more such insights in Software Testing and Automation. Until next time, Happy Testing 🕵🏻 and Learning! 🌱

NewsletterYouTubeBlogLinkedIn

Twitter.

Resources

Originally published at https://automationhacks.io on February 17, 2024.

--

--

Gaurav Singh

Software Engineer passionate about Software Testing, Test Automation {Tooling, Frameworks, Infrastructure}, and scaling teams.