CodeX
Published in

CodeX

NEW BOOK

Learn to Build Production-Grade Microservices with gRPC and Go

An introductory excerpt from gRPC Microservices in Go by Hüseyin Babal

Benefits of gRPC Microservices

Within a typical monolithic application, calling a different business action like calling payment service from checkout service means accessing a class method in separate module which is very easy. If you use microservices, such calls will be converted to a network communication. It can be a call over TCP, HTTP or some sort of event queue to exchange data between services. Handling network calls are more challenging then calling another class method, which can be handled with a simple error handling mechanism like try catch blocks. Even Monoliths are easy to use at first, you may need to decompose them for several reasons, including slow deployments and inefficient resource utilization that clearly affects the feature development and product maintenance. This does not mean Monoliths are bad and Microservices are good; on the contrary, Microservices bring their own challenges like inter-service communication. With the help of gRPC, most of the challenges in Microservices like handling network failures, applying TLS (Transport Layer Security) to service communications can be eliminated. By using the built-in features in gRPC, you can improve both the reliability of your product and the productivity of your entire team by using Go Microservices.

Performance

gRPC provides better performance and security than other protocols like REST with JSON or XML communication, as it uses Protocol Buffers and HTTP/2 over TLS. Protocol Buffers, also known as Protobuf, is a language and platform neutral mechanism for serializing a structural data. This mechanism empowers gRPC to serialize messages into small and compact messages on both server and client side quickly. In the same way, HTTP/2 enables the performance with server-side push, multiplexing and header compression.

Code Generation & Interoperability

Let say that you have Checkout Service and Payment Service that a customer can check out a basket and call a Payment Service to pay for that product within as stated in basket. To access Payment Service, you need to have request and response models on some place like a shared library so that you can access them easily. Reusing a shared request and response models seems handy in Microservices, but actually it is not a good practice, especially if you are using different languages for each microservices. Duplicating models in Checkout Service, which is typically creating another data class to build request object and deserialize response object into, is better choice instead. This is all about preventing a wrong abstraction, as you may already heard the statement “A little duplication is far cheaper than wrong abstraction” (https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction). There is an easier way, which is choosing gRPC to define your messages and generate client stubs so that you can inject this dependency and use it directly in the language you prefer.

Fault Tolerance

Fault tolerance is the ability of a system to continue operating despite system failures. An idempotent operation is the one that has no additional effect even it is called more than once. Idempotency is key to successful fault-tolerant environment since, you need to be sure that, once you retry an operation with same parameters in case of failure or not having expected state, it shouldn’t change the content of actual resource. For example, we may want to retry a user delete operation in case of network failure on response. If the operation returns same result even if you call it more than once, we say this operation is idempotent.

Security

In most of the systems, you may need to setup a security layer to protect your product against unverified sources. gRPC encourages HTTP/2 over SSL/TLS to authenticate and encrypt exchanged data between client and server. More specifically, you can easily set it up that authentication system by using SSL/TLS, ALTS (Application Layer Transport Security), or a Token Based Authentication System.

Streaming

Sometimes you may need to divide response data into several chunks to provide them to the user in a paginated way to reduce bandwidth and return them to the user quickly. Moreover, if they are only interested in certain pages, then it is not meaningful to return all the data at once. In gRPC, besides the pagination, you can also stream this data to the consumer instead of forcing user to do pagination to iteratively get data. Streaming shouldn’t be necessarily on the server side, it can be also on client side, or even in both sides at the same time, which is called bi-directional streaming. In a typical streaming use case, you open the connection once and the data will be streamed through this opened connection. You will see different kinds of usages of streaming use-cases while we are implementing a complete application within this book.

REST vs. gRPC

REST (Representational State Transfer) is widely adopted protocol for microservices, but you may start to think about using gRPC if you have strict requirements like low-latency, multi-language system support, etc. REST is based on HTTP 1.0 Protocol that lets you exchange messages in JSON or XML format between client and server. On the other hand, gRPC is based RPC (Remote Procedure Call) architecture that uses Protocol Buffers binary format to exchange data over HTTP 2.0 Protocol. This does not mean that REST is not compatible with HTTP 2.0, you can setup your REST services based on that protocol with your own custom implementation where it is a built-in feature in gRPC.

When to Use gRPC

If you have strict requirements for browser support, then you need to think of using REST, since you will end up setting up another layer for conversion between HTTP/2 and HTTP/1. However, you can still use gRPC for inter-service communication and attach a gRPC load balancer (https://aws.amazon.com/blogs/aws/new-application-load-balancer-support-for-end-to-end-http-2-and-grpc/) to that service pool for exposing API to the public to have REST compatibility. There are other alternatives like Twirp(https://github.com/twitchtv/twirp), an RPC framework built on Protobuf. Twirp lets you enable REST layer for gRPC services in a way that you can access your endpoints like in the following example to send a POST request with a JSON payload.

curl -X "POST" \
- H "Content-Type: application/json" \
-d '{"name": "dev-cluster"}' \ http://localhost:8080/twirp/github.com/huseyinbabal/microservices-proto/cluster/Create
  • Engineering Managers: can improve developer productivity within their teams by adding the best practices described here into their playbooks. Applying practices will introduce good visibility over the entire product that will help to onboard new employees to the team easily.
  • Software Architects: there are lots of handy examples and architectural designs which are potential references to their decisions for new products or features.
  • Code examples to better understand a specific topic and how it works
  • Automation examples especially with Github Actions to reduce repetitive operations
  • Preparing artifacts for deployment
  • Security best practices

Production-grade Use-cases

As shown in Figure 1, we will try to create an e-commerce product in this book with Go gRPC microservices that is automated within a proper CI/CD pipeline and lives in a Kubernetes environment. In the book, we’ll visit critical parts of the diagram to see how important they are for a typical development lifecycle, how gRPC makes those parts easier to handle, and which technologies to use where.

Figure 1. Architecture diagram of an e-commerce product built with Go Microservices on top of Kubernetes including CI/CD flow and Observability

Summary

  • gRPC performs well in inter-service communications because it uses binary serialization for the data and transfers it through the HTTP/2 protocol.
  • gRPC allows you to do client streaming, server streaming, and bi-directional streaming that allows you to send multiple requests or receive multiple responses in parallel.
  • Stable Client–Server interaction in gRPC Microservices are very easy to accomplish because of automatic code generation.
  • REST is very popular especially due to its wider browser support, but you can still use a gRPC web proxy (e.g. https://github.com/grpc/grpc-web) for REST-to-gRPC conversion.
  • Go is one of the best languages for cloud-native applications, like microservices in kubernetes, due to its high portability.
  • Using HTTP/2 over SSL/TLS end-to-end encryption connection in gRPC eliminates most of the security concerns for a Microservice
  • By the end of the book you will know all of this inside-out!

--

--

Everything connected with Tech & Code. Follow to join our 1M+ monthly readers

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Manning Publications

Follow Manning Publications on Medium for free content and exclusive discounts.