What Is gRPC?
gRPC is a high-performance Remote Procedure call framework that allows developers to connect services across systems. Using gRPC, the client and server apps can communicate flawlessly.
Simply put, gRPC allows a client application to access and use methods on a server application (even in remote machines) as if it’s defined in the same application. It is a major building block for microservices.
Requirements
To follow along with this tutorial, you will need to have:
- The latest version of the Go compiler.
- Protocol Buffer compiler (protoc) version 3
- Go plugins for working with protocol buffers.
To install the protocol buffer compiler, run the command as provided below:
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
The next step is to update your path so you can use the protoc commands:
Golang gRPC Server
For this tutorial, we will build a simple gRPC server that takes the message sent by a client and echoes it back.
Start by creating a working directory:
cd grpc-tut
Next, create a server.go file that will hold the code for the gRPC server:
Open the file with your text editor and add the following lines:
import (
“log”
“net”
)
In the previous code, we import the log and net packages, which will allow us to log errors and establish a listener using the net package.
Next, we will set up the main function and create a listener on port 9001/tcp:
listener, err := net.Listen("tcp", ":9001")
if err != nil {
log.Fatal(err)
}
}
The next step is to import the gRPC package for the Go program. This will allow us to set up a gRPC server and the endpoints we wish to serve before connecting it with the listener on TCP.
Back in the main function, we can create a gRPC server as shown in the following code:
if err := grpServer.Serve(listener); err != nil {
log.Fatal(err)
}
We create a gRPC server using the NewServer() method in the previous code. We then serve the server over the TCP listener we created earlier.
And with that, we have a gRPC server. However, it doesn’t do much. We can extend this by creating a simple echo application.
The application will receive the message from the client and return the same message to the client.
Echo Proto File
To set up our echo application, we will need to create a .proto file. The proto file will hold the definitions for the application.
The first entry in the proto file will be the package declaration. This prevents name collisions in other applications.
package echo;
option go_package = "./echo";
You can change the name to reflect the name of your package.
Once we have the package declaration, we need to add message definitions. This defines a container or structure of the message to receive from the clients:
string body = 1;
}
Next, we need to define the service. In our example, we call the service as echoService as shown:
rpc Echo(Message) returns (Message) {}
}
The service defines a method that a gRPC client will call. The method simply takes the message and returns the message. This creates an echo application.
Compiling the Protocol Buffers
Now, we have the proto defining for our application. Next, we need to generate the classes we will use to read and write data using the Go programming language.
We can do this using the protocol buffer compiler:
The previous commands should generate the Go code required to register and call the gRPC server.
The next step is to define the RPC for the Echo method. We can do this by creating a Go file in the echo directory as:
In the file, add the code as shown:
import (
"fmt"
"golang.org/x/net/context" // get request context
)
type Server struct {
}
func (s *Server) Echo(ctx context.Context, message *Message) (*Message, error) {
fmt.Printf("Message recieved: %s", message.Body)
return &Message{Body: "Hi back!"}, nil
}
The next step is to import the code inside the echo package. Go back to the server.go file and add the following import clause:
You will need to initialize the Go module manager for your project.
In the main server file, add the following lines to create a new chat server and register it:
echo.RegisterEchoServiceServer(grpServer, &s)
And with that, we have the code for the gRPC server out of the way.
gRPC Client
The next step is to build a client that can interact with the gRPC server. Start by creating a file client.go in the main directory.
Let us start with our imports. For this one, we will need the log, context, echo, and gRPC packages
"log"
"golang.org/x/net/context"
"google.golang.org/grpc"
"grpc/echo"
)
Next, let us start with the main function:
// pointer to grpc conn
var conn *grpc.ClientConn
// connect to grpc server (insecure connection)
conn, err := grpc.Dial(":9001", grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
// close conn
defer conn.Close()
// echo service client
e := echo.NewEchoServiceClient(conn)
// message body
message := echo.Message{
Body: "Hi",
}
resp, err := e.Echo(context.Background(), &message)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", resp.Body)
}
The previous code implements a gRPC client, which sends the message “Hi” and gets “Hi Back” from the server.
Testing
Once completed, run the server.go and client.go. If successful, the server should respond with “Hi back” as shown below:
You have successfully built a gRPC server and client in Go.
Conclusion
This guide serves as an absolute basic for implementing gRPC in Go. If you are new to gRPC and protobufs, it may take time to grasp the implementation. However, with a few practices and implementation, you will be in a position to build complex gRPC services. We hope you found this article helpful. Check out other Linux Articles for more tips and tutorials.