fbpx
Hero Illustration
0 Comments

Building High-Performance Applications with gRPC in Golang

As developers, we are familiar with REST APIs for building applications. However, in 2015, Google introduced gRPC as a modern, high-performance RPC (Remote Procedure Call) framework, which is designed to facilitate communication between client and server using Protocol Buffers and HTTP/2 for transmitting data.

What is gRPC?

Before gRPC, the traditional RPC architecture used HTTP, TCP, or UDP for communication between client and server. gRPC, on the other hand, is a system that implements traditional RPC with optimizations.

Protocol Buffers

Protocol Buffers is a data exchange format similar to JSON. However, what sets it apart is the fact that it’s a strongly typed binary data interchange format. Meaning, it allows developers to define the data contract between multiple systems and compile it to a target programming language. In Go, Protocol Buffers can be transported by HTTP/2 automatically.

HTTP/2

HTTP/2 is a protocol for transmitting data over the web, which is used as the base for gRPC. It is an optimized version of HTTP/1.1 that uses binary data instead of text, and it compresses headers to reduce overhead. HTTP/2 is designed to improve web performance, especially for real-time streaming and large data loads. In gRPC, HTTP/2 is used for transmitting data between client and server, and it is optimized for high-performance APIs.

Pros and Cons

gRPC is designed specifically for high-performance applications, real-time streaming, and microservice architecture. It is most suitable for use cases involving high-performance systems, large data loads, and real-time applications.

There are several pros when we use gRPC for our application development:

– gRPC is designed as high-performance, efficient, and scalable which is suitable for large-scale distributed systems.

– gRPC has automated code generation in various programming languages, thus, it can be widely used because the developer can choose their preferred language.

– Since gRPC uses Protocol Buffers to communicate between services, messages can be up to 30 percent smaller than JSON messages. Simply put; lightweight messages. 

– gRPC has four kinds of method definitions: unary, server-side streaming, client-side streaming, and bidirectional streaming.

However, gRPC has several cons:

– Lack of maturity with technology. As in, this technology was first introduced in 2015 and is still relatively new with minimal developer support.

– gRPC has limited browser support since it heavily depends on HTTP/2.

– Messages are unreadable by humans since they are compressed into binary format.

– Learning gRPC may take some time as developers need to become familiar with Protocol Buffers rather than using JSON.

Creating a gRPC Application

In this blog post, we will create a simple application to manage a product using gRPC.

To start developing a gRPC application, we will need to install the following:

• Go version 1.20.12 or the latest.
• PostgreSQL
• Postman

Before creating the application, it is useful to understand the application structure to make following this tutorial easier.

The application structure will look like this:

After installing the prerequisites and understanding the application structure, we can create a new Golang project by following these steps:

1. Create a directory named ‘go-grpc-sample’

2. Open the created directory using preferred text editor such as Visual Studio Code or GoLand.

3. Open the terminal in Visual Studio Code or GoLand then run the command ‘go mod init go-grpc-sample’ to create a file named ‘go.mod’

4. Download the required library dependencies using the following commands:

a. ‘go get -u github.com/google/uuid’ (for auto-generating UUIDs).

b. ‘go get -u google.golang.org/grpc’ (for implementing gRPC).

c. ‘go get -u google.golang.org/protobuf’ (for Google’s Protocol Buffers).

d. ‘go get -u gorm.io/gorm‘ (Golang ORM library).

e. ‘go get -u gorm.io/driver/postgres‘ (for the GORM PostgreSQL driver).

f. ‘go install google.golang.org/protobuf/cmd/protoc-gen-go‘ (the plugin protoc for generating Golang code files from Protocol Buffers).

g. ‘go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1‘ (the plugin protoc for generating Golang code for gRPC service from Protocol Buffers).

After finishing the download and installation of all dependencies. We can start writing the code for the application.

The first step is to create the package `model`, a file representing the entity, we can follow these steps:

1. Create a folder named ‘model’.

2. Inside the ‘model’ folder, create a file named ‘product.go’. This file represents the table in the database. Since we are using Gorm, we can adopt a code first approach and migrate the struct, a collection of fields, as a table in the database.

3. Use the following code as a guide:

In the same folder, ‘model’, create a file named ‘pagination.go’. This file will be used when we want to show the list of data with pagination. Use the following code as a guide:

The next step is to create the repository package, a package for managing external data such as a database. We can follow these steps:

1. In the root directory of the project, create a new folder named ‘repository’.

2. Inside the ‘repository’ folder, create a file named ‘repository_product.go’, this file is used for processing queries and mapping data related to products. This file contains functions for retrieving a list of products, retrieving product details, creating, updating, and deleting products. While it is common practice to divide these functions into separate files to adhere to the single responsibility principle, we will keep them all in one file for simplicity.

3. Use the following code as a guide:

After creating the repository, we will create a Protocol Buffers file. This is a file to describe the message and service structure. We can follow these steps:

1. In the root directory of the project, create a new folder ‘proto/product’.

2. Inside the ‘proto/product’ folder, create a file named ‘product.proto’, this file is a Protocol Buffers with version 3. It contains Protocol Buffers messages for request, response binaries, and service methods that are implemented in gRPC.

3. Use the following code as a guide:

To generate Protocol Buffers files into Golang code, we can follow these steps:

1. Open the terminal and navigate to the directory containing the Protocol Buffers file.

2. Execute the command:
‘protoc –go_out=. –go_opt=paths=source_relative –go-grpc_out=. –gogrpc_opt=paths=source_relative product.proto’

3. If the ‘protoc’ command is not found, install it based on our operating system:

a. For Linux/WSL use:
‘sudo apt install protobuf-compiler’

b. MacOS use:
‘brew install protobuf’

c. For Windows, download the Windows distribution from this link protobuf, unzip the file, and add the folder path to the system environment variables.

4. After executing the command, two files will be generated:

a. ‘product.pb.go’, this file contains the Protocol Buffers message.

b. ‘product_grpc.pb.go’, this file contains the service methods of the Protocol Buffers.

The next step is to create the ‘gapi’ package, which is a gRPC API package. 

Follow these steps:

1. In the root directory of the project, create a folder named ‘gapi’.

2. Inside the ‘gapi’ folder, create a file named ‘gapi_product.go’, this file serves as a service layer where we can implement our logic. It contains the service methods defined in file ‘product.proto’ file.

3. Use the following code as a guide:

Next, we’ll create the initialization file to initialize database connection and gRPC server.

Let’s follow these steps:

1. In the root directory of the project, create a new folder named ‘initialization’.

2. Inside the ‘initialization’ folder, create a file named ‘initialization.go’. This file will contain the database and server initialization. It also includes the database connection configuration, network settings, address, and service registration.

3. Make sure to change the DSN (Data Source Name) for connecting to the database and ensure that the database has been created before proceeding with this step. In this example, we will use TCP as a network with port 1200. Note that we may adjust the port with the available ports.

4. Use the following code as a guide:

Now, we’ll create the main file that serves as an entry point to the application. 

Follow these steps:

1. In the root directory of the project, create a file named ‘main.go’. To run the application, execute the command ‘go run main.go’. In the code snippet, we’ll use auto-migration

to create the database table based on the model struct. Before proceeding, we need to ensure that we have created the database based on the DSN setting.

2. Use the following code as a guide:

Test the Application

To test the application we have created, we can use Postman and follow these steps:

1. Select ‘gRPC’ to initialize a new request.

2. Select the ‘Service definition’ tab and click ‘Import .proto file’.

3. Locate the proto file that we created before, then click ‘Next’.

4. Replace the ‘URL’ with the one we defined before. For this example, we will use ‘localhost:1200’. Then, select one of the methods from the proto file. This should display five service methods.

5. Navigate to the ‘Message’ tab and click ‘Use Example Message’ to generate a sample message for the method. We can customize the message according to our requirements. After modifying the message then click ‘Invoke’.

6. As a result, the application will return a response data according to the message we have defined in proto file.

Conclusion

gRPC is not a replacement for REST or GraphQL, but rather an alternative API option for application development. It offers the option of utilizing a lightweight RPC structure that can be beneficial when optimizing for speed and minimizing data load. When transitioning resources or creating new microservices with a focus on maximizing efficiency, gRPC becomes a viable option.

It’s also important to take note of the pros and cons that comes with gRPC. We can identify at least four pros for the applications such as high performance, capability to handle high data loads, support for real-time applications, and consistency of contract between microservices. 

However, we also need to address its weaknesses, including at least four cons such as lack of maturity, limited browser support, unreadable format, and a steeper learning curve.

To sum up, this article has given you a good understanding of gRPC. Hopefully, it can help you choose the right API for your application, whether it’s new or already running

References

https://aws.amazon.com/compare/the-difference-between-grpc-and-rest/
https://grpc.io/
https://grpc.io/docs/languages/go/basics/
https://protobuf.dev/
https://dev.to/karankumarshreds/protocol-buffers-and-grpc-in-go-3eil
https://santoshk.dev/posts/2022/grpc-for-absolute-beginners-in-go/
https://www.altexsoft.com/blog/what-is-grpc/
https://pkg.go.dev/golang.org/x/net/http2

Author: Steven Aldo Sutanto, Analyst Programmer

Contact us to learn more!

Please complete the brief information below and we will follow up shortly.

    ** All fields are required
    Leave a comment