Building Reverse Proxy (gRPC-Gateway)
gRPC API with protocol buffers

In the last article, we built the API design for a social media application. We wrote the definition of five REST endpoints for a Post using Protocol Buffers as well as the HTTP annotations for each endpoint, we also generated the code to implement a reverse proxy using the grpc-gateway plugin.
In this article, we’ll continue building the API and the next step is implementing the reverse proxy.
If you missed the last article, I’d recommend reading the articles in the following order:
- Go API Design With Protocol Buffers and gRPC
- Building Reverse Proxy (gRPC-Gateway)
- Go API — Database Connection
We’ll be using docker and docker-compose, so I recommend installing docker and docker-compose first and make sure you are able to run containers.
Navigate to your GOPATH
, if you don’t know what’s your go path directory, you can run echo $GOPATH
and that will print the correct path. In there create the src/github/com/yaairfernando
folder structure, replacing the last directory with your GitHub handle. Once you are there, create the following project structure:
mkdir socialMedia
cd socialMedia
touch docker-compose.yaml
All right, let’s start by defining the docker-compose yaml file.
From the above yaml file, we are defining the proxy
service, from the configuration of this service we can see that the container name is proxy
, and the image that will use is sma:proxy
, in case the docker image does not exist, it will build it from the ./proxy
folder, we are also passing as arguments a GitHub access token, this is only necessary if you created a private repo for the API design from the previous article.
If so, you’ll need to pass a GitHub access token to the docker image to be able to access private repositories from the docker file.
We also specify a command and two environment variables to be run: one to specify the rest port where the server will be running, and a grpc URL, which points to the service that the proxy will be proxying requests.
We also specify that the port that this service will expose is 9094
and internally would be 8081
.
Let’s now create a proxy folder and the main.go
file:
mkdir proxy
cd proxy
touch main.go
Inside the proxy folder, we’ll run this command to create a go module
go mod init github.com/yaairfernando/proxy
This will create a go.mod
file under the proxy folder.
module github.com/yaairfernando/proxygo 1.18
The main.go
file looks like this:
The main function is only initializing a new server passing the grpcURL
, restPort
, and calling the start method on the server instance.
Let’s see what the server file looks like. Create the server folder and a server.go
file.
mkdir server
cd server
touch server.go
This server file has all the logic to register the handler for the Posts
resource, add a simple logger, create an HTTP server and listen on the specified port.
- In line 36 we create a new server mux
- In line 38, we wrapped that server with a simple logger
- In line 40, we register all the handlers. In our case, we only have one for the
Posts
resource at the moment - Lastly, in lines 45–49 we create an HTTP server passing the handler and start listening
As you can see, some helper functions are not defined in this file. I added them to a utils
file.
All right, let’s now create the Dockerfile
:
I will not go deep into what this docker file is doing, but essentially it uses a Golang image as the builder, sets some go environment variables, sets the working directory, and copies the go.mod
file. After that, it downloads all dependencies, copies the rest of the files, and lastly, sets the entry point.
This is the go.mod
file with all the packages that are used.
This is the final folder structure for the project:

We are almost done. Now, let’s download the go packages we need by running the following commands in the proxy folder:
go mod download
go mod tidy
As you can see for the sma
package, we specified that we want version v0.1.0
from that package, but when we built the API design we did not create any versions. Let’s do that.
Generate Git tag
Go back to where you have the sma
project, and let’s create a tag:
git tag v0.1.0
And push it to the repository:
git push origin v0.1.0
Now, back in the proxy
folder, run this command to download that version of the sma
package:
go get github.com/yaairfernando/sma@v0.1.0
The above command will download the sma
package with the specified version.
One last thing before we build the service, add a .env
file with your GitHub access token in case your repo for the API design is private.
GITHUB_ACCESS_TOKEN=your_gihub_access_token
Build Docker Service
We can now build the proxy service by running the following command in the root folder:
docker-compose up --build -d proxy
When running this command you’ll get some errors saying to download some packages that we have specified in the go.mod
file. Just download the packages by running go mod download package_path
. And re-run the docker-compose command.
After the build finishes, we should be able to see the container running. Sending a POST request to http://localhost:9094/v1/posts
will not work yet, but we can see the log.

That is all for this article. We have implemented the reverse proxy. In the next article, we’ll continue building the API.
Stay tuned, and thank you for reading!