Supporting REST and HTML with a gRPC Microservice
- Getting Started
- Exercising the Server with Evans
- Setting Up Envoy Proxy
- Creating a Docker Container for Envoy
- Annotating the API Definition
- Including Dependencies
- Transcoding HTTP GET Verbs
- Transcoding an HTTP POST Verb
- Transcoding Other Verbs
- Generating an Annotated Protobuf File
- Configuring Envoy for Transcoding
- Adding a Transcoding Filter
- Running the Servers
- Other Options with protoc
- Generating Concurrency Code
- Where to Go from Here?
Any microservice can become a gRPC microservice.
gRPC and protobuf work together to bring more structure to building out APIs, even if your service has to work across different clients or support streams of data.
The system generates model and networking code for the protocol — you define the API using a .proto file which is compiled into native code for the different clients.
Although some clients may not be able to take advantage of gRPC, that’s OK because gRPC includes support for classic HTTP and REST as well.
Moreover, gRPC is designed for machines to talk to other machines, and the data packets can be much smaller than corresponding REST and HTML traffic.
gRPC shines in bandwidth-constrained uses cases, such as a service shares readings from hundreds of sensors in an urban farm with a central server that manages the building’s HVAC, or a service that calculates fees for a personal shopper mobile app.
In this tutorial, you’ll work with an app that creates TODOs and learn how to:
- Build a .proto file so it maps HTTP URLs to gRPC services.
- Configure an Envoy proxy server to transcode HTTP/JSON to gRPC.
- You’re familiar with gRPC tools, such as Evans and protoc. If not, go through the gRPC and Server Side Swift: Getting Started article. Then come back here to build on what you learned.
- You have basic experience with Docker. If you want to brush up, you’ll find Developing and Testing Server-Side Swift with Docker and Vapor handy. Use Docker Desktop if you prefer GUI to CLI.
- You’re familiar with command line basics, such as changing directories, downloading dependencies, and navigating git repos.
These instructions work for Apple Silicon and Intel-based Macs, as well as x86_64 and AArch64 versions of Linux.
Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.
The starter project contains a Vapor app and a database server for managing TODO items. It uses gRPC to communicate with clients.
Open the envoy folder to find some configuration files. You’ll modify them for the Envoy proxy.
Make sure you have these prereqs installed:
- protoc to generate gRPC files.
- Postman, or something similar, to send HTTP requests to the server.
- Evans, or something similar, to generate gRPC requests.
If you need to install these, step through the first few sections of gRPC and Server Side Swift: Getting Started.
When installing protoc on Linux, be sure to add both the bin and include directories from the extracted archive to your PATH.
Now that your tools are set up, it’s time to start things up with Docker Compose and test things out with Evans.
Open Terminal and navigate to the root directory of the project. Run the following commands to start the vapor app and database servers:
docker compose up db -d
docker compose up app -d
Setting the `-d` option runs the process in the background, which is helpful when you’re viewing console output with Docker Desktop.
If you’re running in CLI, you can omit the `-d` option. You’ll want to use Screen to run the command, or a new terminal window or tab.
Exercising the Server with Evans
Now that both servers are running, you’ll use Evans to add a few TODO items.
Navigate to the root of the project — the directory that contains todo.proto — and type this command:
evans repl --host localhost --port 1234 --proto ./todo.proto
The above command will bring you into the evans repl (Read Evaluate Print Loop) and allow you to call gRPC endpoints defined in todo.proto.
Next, you’ll create new TODO items and generate a list of them with Evans:
- To create items, you’ll use
call createTodoand follow the prompts.
- To generate a list of TODO items, you’ll use
- To close the app, unsurprisingly, you’ll use
Take a moment to review the animated screenshot. We use Evans to create, complete, delete, and list Todo items.
Evans uses gRPC to communicate with the servers. It doesn’t support HTTP yet.
To see for yourself, use Postman or another REST client to navigate to
http://localhost:1234/. The server will respond with an error code of
415 Unsupported Media Type.
If you need to bring down the servers, use Docker desktop or type
docker compose down in your Terminal.
Setting Up Envoy Proxy
Lyft designed the Envoy proxy server. Its core features include gRPC, load balancing and HTTP/2. Google Cloud proxy works on top of Envoy. Envoy is built on the learnings of NGINX and HAProxy, and can run in parallel with them providing common features.
The other parts of your application are running in Docker containers, and now it’s time to add one for Envoy.
Creating a Docker Container for Envoy
Find and open docker-compose.yml with a text editor so that you can add an entry. You’re working with
yml, so make sure you indent and use whitespace as shown.
At the bottom of the file, add the following entry for
Envoy, below the entry for
This entry uses a standard build of the Envoy proxy from Docker hub and does the following:
volumessection copies a configuration file into the server.
8082for HTTP traffic.
- Then it exposes port
9901— the administrative site for Envoy and used only to confirm Envoy is running.
Save the changes to docker-compose.yml. Start the Envoy server by typing
docker compose up envoy -d in Terminal.
Confirm that Envoy is running by pointing a browser to
127.0.0.1:9901 to bring up the administrative site. Next, navigate to
127.0.0.1:8082 which will redirect to Envoy’s main website.
You’ve just deployed a configuration example from Envoy’s documentation, and it wasn’t even that hard! Next, you’ll modify it so it can transcode HTTP and gRPC traffic.
Annotating the API Definition
In this section, you’ll annotate the todo.proto file. You’ll also use protoc to generate a file for Envoy to use.