Chapter 8. The gRPC Ecosystem

In this chapter, we’ll explore some of the projects that are not part of the core gRPC implementation but could be quite useful in building and running gRPC applications for a real-world use case. These projects are part of the gRPC Ecosystem parent project, and none of the technologies mentioned here are mandatory to run gRPC applications. If you have a similar requirement that a given project offers, explore and evaluate those technologies.

Let’s begin our discussion with the gRPC gateway.

gRPC Gateway

The gRPC gateway plug-in enables the protocol buffer compiler to read the gRPC service definition and generate a reverse proxy server, which translates a RESTful JSON API into gRPC. This is specifically written for Go, to support invoking gRPC service from both gRPC and HTTP client applications. Figure 8-1illustrates how it provides the ability to invoke gRPC service in both gRPC and RESTful ways.

As shown in the figure, we have a ProductInfo service contract and using the contract we build a gRPC service called ProductInfoService. Earlier we built a gRPC client to talk with this gRPC service. But here, instead of building a gRPC client we will build a reverse proxy service, which exposes RESTful API for each remote method in the gRPC service and accepts HTTP requests from REST clients. Once it receives an HTTP request, it translates the request into a gRPC message and calls the remote method in the backend service. The response message from the backend server again converts back to an HTTP response and replies to the client.

gRPC gateway
Figure 8-1. gRPC gateway

To generate a reverse proxy service for the service definition, we first need to map the gRPC methods to the HTTP resources by updating the service definition. Let’s get the same ProductInfo service definition we created, to add mapping entries. Example 8-1 shows the updated protocol buffer definition.

Example 8-1. Updates protocol buffer definition of ProductInfo service
syntax = "proto3";

import "google/protobuf/wrappers.proto";
import "google/api/annotations.proto"; 1

package ecommerce;

service ProductInfo {
   rpc addProduct(Product) returns (google.protobuf.StringValue) {
       option (google.api.http) = { 2
           post: "/v1/product"
           body: "*"
       };
   }
   rpc getProduct(google.protobuf.StringValue) returns (Product) {
        option (google.api.http) = { 3
            get:"/v1/product/{value}"
        };
   }
}

message Product {
   string id = 1;
   string name = 2;
   string description = 3;
   float price = 4;
}
1

Import the google/api/annotations.proto proto file to add annotation support to the protocol definition.

2

Add gRPC/HTTP mapping to the addProduct method. Specify the URL path template (/v1/product), the HTTP method (“post”), and what the message body looks like. * is used in the body mapping to define that every field not bound by the path template should be mapped to the request body.

3

Add gRPC/HTTP mapping to the getProduct method. Here it is a GET method with the URL path template as /v1/product/{value} and the ProductID passed as the path parameter.

There are additional rules we need to know when we are mapping gRPC methods to HTTP resources. A few important rules are listed next. You can refer to the Google API Documentation for more details about HTTP to gRPC mapping:

  • Each mapping needs to specify a URL path template and an HTTP method.

  • The path template can contain one or more fields in the gRPC request message. But those fields should be nonrepeated fields with primitive types.

  • Any fields in the request message that are not in the path template automatically become HTTP query parameters if there is no HTTP request body.

  • Fields that are mapped to URL query parameters should be either a primitive type or a repeated primitive type or a nonrepeated message type.

  • For a repeated field type in query parameters, the parameter can be repeated in the URL as ...?param=A&param=B.

  • For a message type in query parameters, each field of the message is mapped to a separate parameter, such as ...?foo.a=A&foo.b=B&foo.c=C.

Once we write the service definition, we need to compile it using the protocol buffer compiler and generate a source code of reverse proxy service. Let’s talk about how to generate code and implement the server in the Go language.

Before we can compile the service definition, we need to get a few dependent packages. Use the following command to download the packages:

go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
go get -u github.com/golang/protobuf/protoc-gen-go

After downloading the packages, execute the following command to compile the service definition (product_info.proto) and to generate the stub:

protoc -I/usr/local/include -I. 
-I$GOPATH/src 
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis 
--go_out=plugins=grpc:. 
product_info.proto

Once we execute the command, it will generate a stub (product_info.pb.go) in the same location. Apart from the generated stub, we also need to create a reverse proxy service to support RESTful client invocation. This reverse proxy service can be generated by the gateway plug-in supported in the Go compiler.

Note

The gRPC gateway is only supported in Go, which means we cannot compile and generate a reverse proxy service for the gRPC gateway in other languages.

Let’s generate a reverse proxy service from service definition by executing the following command:

protoc -I/usr/local/include -I. 
-I$GOPATH/src 
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis 
--grpc-gateway_out=logtostderr=true:. 
product_info.proto

Once we execute the command, it will generate a reverse proxy service (product_info.pb.gw.go) in the same location.

Let’s create the listener endpoint for the HTTP server and run the reverse proxy service we just created. Example 8-2 illustrates how to create a new server instance and register the service to listen to the inbound HTTP requests.

Example 8-2. HTTP reverse proxy in Go language
package main

import (
  "context"
  "log"
  "net/http"

  "github.com/grpc-ecosystem/grpc-gateway/runtime"
  "google.golang.org/grpc"

  gw "github.com/grpc-up-and-running/samples/ch08/grpc-gateway/go/gw" 1
)

var (
  grpcServerEndpoint = "localhost:50051" 2
)

func main() {
  ctx := context.Background()
  ctx, cancel := context.WithCancel(ctx)
  defer cancel()

  mux := runtime.NewServeMux()
  opts := []grpc.DialOption{grpc.WithInsecure()}
  err := gw.RegisterProductInfoHandlerFromEndpoint(ctx, mux,
      grpcServerEndpoint, opts) 3
  if err != nil {
     log.Fatalf("Fail to register gRPC gateway service endpoint: %v", err)
  }

  if err := http.ListenAndServe(":8081", mux); err != nil { 4
     log.Fatalf("Could not setup HTTP endpoint: %v", err)
  }
}
1

Import the package to where the generated reverse-proxy code exists.

2

Specify the gRPC server endpoint URL. Make sure the backend gRPC server is running properly in the mentioned endpoint. Here we used the same gRPC service created in Chapter 2.

3

Register the gRPC server endpoint with the proxy handler. At runtime, the request multiplexer matches HTTP requests to patterns and invokes the corresponding handler.

4

Start listening to the HTTP requests on the port (8081).

Once we build an HTTP reverse-proxy server, we can test it by running both the gRPC server and the HTTP server. In this case, the gRPC server is listening on port 50051 and the HTTP server is listening on port 8081.

Let’s make a few HTTP requests from curl and observe the behavior:

  1. Add a new product to the ProductInfo service.

    $ curl -X POST http://localhost:8081/v1/product
            -d '{"name": "Apple", "description": "iphone7", "price": 699}'
    
    "38e13578-d91e-11e9"
  2. Get the existing product using ProductID:

    $ curl http://localhost:8081/v1/product/38e13578-d91e-11e9
    
    {"id":"38e13578-d91e-11e9","name":"Apple","description":"iphone7",
    "price":699}
  3. Added to the reverse proxy service, the gRPC gateway also supports generating the swagger definition of the reverse proxy service by executing the following command:

    protoc -I/usr/local/include -I. 
      -I$GOPATH/src 
      -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/
      third_party/googleapis 
      --swagger_out=logtostderr=true:. 
      product_info.proto
  4. Once we execute the command, it generates a swagger definition for the reverse proxy service (product_info.swagger.json) in the same location. For our ProductInfo service, generated swagger definition looks like this:

    {
     "swagger": "2.0",
     "info": {
       "title": "product_info.proto",
       "version": "version not set"
     },
     "schemes": [
       "http",
       "https"
     ],
     "consumes": [
       "application/json"
     ],
     "produces": [
       "application/json"
     ],
     "paths": {
       "/v1/product": {
         "post": {
           "operationId": "addProduct",
           "responses": {
             "200": {
               "description": "A successful response.",
               "schema": {
                 "type": "string"
               }
             }
           },
           "parameters": [
             {
               "name": "body",
               "in": "body",
               "required": true,
               "schema": {
                 "$ref": "#/definitions/ecommerceProduct"
               }
             }
           ],
           "tags": [
             "ProductInfo"
           ]
         }
       },
       "/v1/product/{value}": {
         "get": {
           "operationId": "getProduct",
           "responses": {
             "200": {
               "description": "A successful response.",
               "schema": {
                 "$ref": "#/definitions/ecommerceProduct"
               }
             }
           },
           "parameters": [
             {
               "name": "value",
               "description": "The string value.",
               "in": "path",
               "required": true,
               "type": "string"
             }
           ],
           "tags": [
             "ProductInfo"
           ]
         }
       }
     },
     "definitions": {
       "ecommerceProduct": {
         "type": "object",
         "properties": {
           "id": {
             "type": "string"
           },
           "name": {
             "type": "string"
           },
           "description": {
             "type": "string"
           },
           "price": {
             "type": "number",
             "format": "float"
           }
         }
       }
     }
    }

So now we have implemented the HTTP reverse proxy service for our gRPC service using the gRPC gateway. This way we can expose our gRPC server to use in HTTP client applications. You can get more information about gateway implementation from the gRPC gateway repository.

As we mentioned earlier, the gRPC gateway is only supported in Go. The same concept is also known as HTTP/JSON transcoding. Let’s talk more about HTTP/JSON transcoding in the next section.

HTTP/JSON Transcoding for gRPC

Transcoding is the process of translating HTTP JSON calls to RPC calls and passing them to the gRPC service. This is useful when the client applications don’t have support for gRPC and need to provide access to talk to the gRPC service via JSON over HTTP. There is a library written in C++ languages to support the HTTP/JSON transcoding called grpc-httpjson-transcoding, and it is currently used in Istio and Google cloud endpoint.

The Envoy proxy also supports transcoding by providing an HTTP/JSON interface to the gRPC service. Similar to the gRPC gateway, we need to provide the service definition with HTTP mapping for the gRPC service. It uses the same mapping rules specified in the Google API documentation. So the service definition we modified in Example 8-1 can also be applied to the HTTP/JSON transcoding.

For example, the Product Info service’s getProduct method is defined in the .proto file with its request and response types like the following:

   rpc getProduct(google.protobuf.StringValue) returns (Product) {
        option (google.api.http) = {
            get:"/v1/product/{value}"
        };
   }

If a client calls this method by sending a GET to the URL http://localhost:8081/v1/product/2, the proxy server creates a google.protobuf.StringValue with a value of 2 and then calls the gRPC method getProduct() with it. The gRPC backend then returns the requested Product with the ID 2, which the proxy server converts to JSON format and returns to the client.

Now that we’ve covered HTTP/JSON transcoding, in the next section, we’ll discuss another important concept, called gRPC server reflection.

The gRPC Server Reflection Protocol

Server reflection is a service defined on a gRPC server that provides information about publicly accessible gRPC services on that server. In simple terms, server reflection provides service definitions of the services registered on a server to the client application. So the client doesn’t need precompiled service definitions to communicate with the services.

As we discussed in Chapter 2, for the client application to connect and communicate with the gRPC service, it must have the service definition of that service. We first need to compile the service definition and generate the corresponding client stub. Then we need to create client application calling methods of the stub. With the gRPC server reflection, we don’t need to precompile service definitions to communicate with the service.

The service reflection is useful when we build a command-line (CLI) tool for debugging the gRPC server. We don’t need to provide service definitions for the tool, but instead we provide the method and the text payload. It sends the binary payload to the server and takes the response back to the user in a human-readable format. In order to use service reflection, we first need to enable it on the server side. Example 8-3 illustrates how to enable server reflection.

Example 8-3. Enable server reflection in the gRPC Go server
package main

import (
  ...

  pb "productinfo/server/ecommerce"
  "google.golang.org/grpc"
  "google.golang.org/grpc/reflection" 1
)

func main() {
  lis, err := net.Listen("tcp", port)
  if err != nil {
     log.Fatalf("failed to listen: %v", err)
  }
  s := grpc.NewServer()
  pb.RegisterProductInfoServer(s, &server{})
  reflection.Register(s) 2
  if err := s.Serve(lis); err != nil {
     log.Fatalf("failed to serve: %v", err)
  }
}
1

Import the reflection package to access reflection APIs.

2

Register reflection service on your gRPC server.

After enabling server reflection in your server application, you can use the gRPC CLI tool to check your server.

Note

The gRPC CLI tool comes with the gRPC repository. It supports many functionalities, such as the list server services and methods, and sending and receiving RPC calls with metadata. As of this writing, you need to build the tool from the source code. For details on how to build and use the tool, refer to the gRPC CLI tool repository.

Once you build the gRPC CLI tool from the source code, you can use it to check services. Let’s try to understand this using our product management service that we built in Chapter 2. Once you start the gRPC server of the product management service, then you can run the CLI tool to retrieve the service information.

Here are the actions that you can execute from the CLI tool:

List services

Run the following command to list all public services in endpoint localhost:50051:

$ ./grpc_cli ls localhost:50051

Output:
ecommerce.ProductInfo
grpc.reflection.v1alpha.ServerReflection
List service details

Run the following command by giving the service’s full name (in the format of <package>.<service>) to inspect the service:

$ ./grpc_cli ls localhost:50051 ecommerce.ProductInfo -l

Output:
package: ecommerce;
service ProductInfo {
rpc addProduct(ecommerce.Product) returns
(google.protobuf.StringValue) {}
rpc getProduct(google.protobuf.StringValue) returns
(ecommerce.Product) {}
}
List method details

Run the following command by giving the method’s full name (in the format of <package>.<service>.<method>) to method details:

$ ./grpc_cli ls localhost:50051 ecommerce.ProductInfo.addProduct -l

Output:
rpc addProduct(ecommerce.Product) returns
(google.protobuf.StringValue) {}
Inspect message types

Run the following commands by giving the full name of the message type (in the format of <package>.<type>) to inspect the message type:

$ ./grpc_cli type localhost:50051 ecommerce.Product

Output:
message Product {
string id = 1[json_name = "id"];
string name = 2[json_name = "name"];
string description = 3[json_name = "description"];
float price = 4[json_name = "price"];
}
Call remote methods

Run the following commands to send remote calls to the server and get the response:

  1. Call the addProduct method in the ProductInfo service:

    $ ./grpc_cli call localhost:50051 addProduct "name:
                 'Apple', description: 'iphone 11', price: 699"
    
    Output:
    connecting to localhost:50051
    value: "d962db94-d907-11e9-b49b-6c96cfe0687d"
    
    Rpc succeeded with OK status
  2. Call getProduct method in the ProductInfo service:

    $ ./grpc_cli call localhost:50051 getProduct "value:
                 'd962db94-d907-11e9-b49b-6c96cfe0687d'"
    
    Output:
    connecting to localhost:50051
    id: "d962db94-d907-11e9-b49b-6c96cfe0687d"
    name: "Apple"
    description: "iphone 11"
    price: 699
    
    Rpc succeeded with OK status

Now we can enable server reflection in the gRPC Go server and test it using the CLI tool. We can also enable server reflection in our gRPC Java server. If you are more familiar with Java, you can refer to the Java samples in the source code repository.

Let’s discuss another interesting concept called gRPC middleware.

gRPC Middleware

In basic terms, the middleware is a software component in a distributed system that is used to connect different components to route requests generated by the client to the backend server. In gRPC Middleware, we are also talking about running code before and after the gRPC server or client application.

In fact, gRPC middleware is based on the interceptor concept that we learned in Chapter 5. It’s a Go-based collection of interceptors, helpers, and utils that you will require when building gRPC-based applications. It allows you to apply multiple interceptors at the client or server side as a chain of interceptors. Also, as interceptors are commonly used for implementing common patterns such as auth, logging, message, validation, retries, or monitoring, the gRPC Middleware project acts as the go-to point for such reusable functionalities for Go. In Example 8-4, we have shown the common usage of the gRPC Middleware package. Here we have used it for applying multiple interceptors for both unary and streaming messaging.

Example 8-4. interceptor chaining at the server side with Go gRPC Middleware
import "github.com/grpc-ecosystem/go-grpc-middleware"

orderMgtServer := grpc.NewServer(
    grpc.Unaryinterceptor(grpc_middleware.ChainUnaryServer( 1
        grpc_ctxtags.UnaryServerinterceptor(),
        grpc_opentracing.UnaryServerinterceptor(),
        grpc_prometheus.UnaryServerinterceptor,
        grpc_zap.UnaryServerinterceptor(zapLogger),
        grpc_auth.UnaryServerinterceptor(myAuthFunction),
        grpc_recovery.UnaryServerinterceptor(),
    )),
    grpc.Streaminterceptor(grpc_middleware.ChainStreamServer( 2
        grpc_ctxtags.StreamServerinterceptor(),
        grpc_opentracing.StreamServerinterceptor(),
        grpc_prometheus.StreamServerinterceptor,
        grpc_zap.StreamServerinterceptor(zapLogger),
        grpc_auth.StreamServerinterceptor(myAuthFunction),
        grpc_recovery.StreamServerinterceptor(),
    )),
    )
1

Add a unary interceptor chain for the server.

2

Add a streaming interceptor chain for the server.

The interceptors are invoked in the same order that they have registered with the Go gRPC Middleware. The project also offers some reusable interceptors for common patterns. Here are some of those common patterns and interceptor implementations:

Auth
grpc_auth

A customizable (via AuthFunc) piece of auth middleware.

Logging
grpc_ctxtags

A library that adds a Tag map to context, with data populated from the request body.

grpc_zap

Integration of zap logging library into gRPC handlers.

grpc_logrus

Integration of logrus logging library into gRPC handlers.

Monitoring
grpc_prometheus

Prometheus client-side and server-side monitoring middleware.

grpc_opentracing

OpenTracing client-side and server-side interceptors with support for streaming and handler-returned tags.

Client
grpc_retry

A generic gRPC response code retry mechanism, client-side middleware.

Server
grpc_validator

Codegen inbound message validation from .proto options.

grpc_recovery

Turn panics into gRPC errors.

ratelimit

gRPC rate-limiting by your own limiter.

The usage of Go gRPC Middleware at the client side is exactly the same. Example 8-5 shows a code snippet of the client-side interceptor chaining with Go gRPC Middleware.

Example 8-5. interceptor chaining at the client side with Go gRPC Middleware
import "github.com/grpc-ecosystem/go-grpc-middleware"

clientConn, err = grpc.Dial(
   address,
     grpc.WithUnaryinterceptor(grpc_middleware.ChainUnaryClient(
          monitoringClientUnary, retryUnary)), 1
     grpc.WithStreaminterceptor(grpc_middleware.ChainStreamClient(
          monitoringClientStream, retryStream)), 2
)
1

Client-side unary interceptor chaining.

2

Client-side streaming interceptor chaining.

Similar to the server side, the interceptors are executed in the order that they registered with the client.

Next, we will talk about how we can expose the health status of the gRPC server. In a high-availability system, it is essential to have a way to check the health status of the server, so that we can periodically check and take actions to mitigate the damage.

Health Checking Protocol

gRPC defines a health checking protocol (Health Checking API) that allows the gRPC services to expose the server status so that the consumers can probe the server’s health information. The health of the server is determined if the server responds with an unhealthy status when it is not ready to handle the RPC or does not respond at all for the health probe request. The client can act accordingly if the response denotes an unhealthy status or a response is not received within some time window.

The gRPC Health Checking Protocol defines an API based on gRPC. Then a gRPC service is used as the health checking mechanism for both simple client-to-server scenarios and other control systems such as load balancing. Example 8-6 shows the standard service definition of the gRPC health checking interface.

Example 8-6. gRPC service definition of the Health Checking API
syntax = "proto3";

package grpc.health.v1;

message HealthCheckRequest { 1
  string service = 1;
}

message HealthCheckResponse { 2
  enum ServingStatus {
    UNKNOWN = 0;
    SERVING = 1;
    NOT_SERVING = 2;
  }
  ServingStatus status = 1;
}

service Health {
  rpc Check(HealthCheckRequest) returns (HealthCheckResponse); 3

  rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); 4
}
1

The health check request message structure.

2

The health check response with the serving status.

3

The client can query the server’s health status by calling the Check method.

4

The client can call the Watch method to perform a streaming health check.

The implementation of the health check service is very similar to any conventional gRPC service. Often you will run a health checking service and related gRPC business services together in the same gRPC server instance using multiplexing (which we discussed in Chapter 5). Since it is a gRPC service, doing a health check is the same as doing normal RPC. It also offers a granular service health semantics that includes details such as per-service health status. Also, it is able to reuse all the existing information on the server and have full control over it.

Based on the server interface shown in Example 8-6, a client can call the Check method (with an optional parameter service name) to check the health status of a particular service or the server.

Additionally, the client can also call the Watch method to perform a streaming health check. This uses a server streaming messaging pattern, which means once the client calls this method, the server starts sending messages indicating the current status and sends subsequent new messages whenever the status changes.

These are the key points to know in the gRPC Health Checking Protocol:

  • To serve the status of each service registered in the server, we should manually register all the services, along with their status in the server. We also need to set the server’s overall status with an empty service name.

  • Each health check request from the client should have a deadline set to it, so the client can determine the server status as unhealthy if the RPC is not finished within the deadline period.

  • For each health check request, the client can either set a service name or set as empty. If the request has a service name and it is found in the server registry, a response must be sent back with an HTTP OK status and the status field of the HealthCheckResponse message should be set to the status of the particular service (either SERVING or NOT_SERVING). If the service is not found in the server registry, the server should respond with a NOT_FOUND status.

  • If the client needs to query the overall status of the server instead of a specific service, the client can send the request with an empty string value so the server responds back with the server’s overall health status.

  • If the server doesn’t have a health check API, then the client should deal with it themselves.

The health check services are consumed by other gRPC consumer or intermediate subsystems such as load balancers or proxies. Rather than implementing a client from scratch, you can use the existing implementation of health checking clients such as grpc_health_probe.

gRPC Health Probe

The grpc_health_probe is a utility provided by the community to check the health status of a server that exposes its status as a service through the gRPC Health Checking Protocol. It’s a generic client that can communicate with the gRPC standard health check service. You can use the grpc_health_probe_ binary as a CLI utility as shown in the following:

$ grpc_health_probe -addr=localhost:50051 1

healthy: SERVING
$ grpc_health_probe -addr=localhost:50052 -connect-timeout 600ms 
 -rpc-timeout 300ms 2

failed to connect service at "localhost:50052": context deadline exceeded
exit status 2
1

A health checking request for gRPC server running on localhost port 50051.

2

A health checking request with few more additional parameters related to the connectivity.

As shown in the preceding CL output, grpc_health_probe_ makes an RPC to /grpc.health.v1.Health/Check. If it then responds with a SERVING status, the grpc_health_probe will exit with success; otherwise, it exits with a nonzero exit code.

If you are running your gRPC applications on Kubernetes, then you can run the grpc_health_probe to check to define Kubernetes’s liveness and readiness checks for your gRPC server pods.

For that, you can bundle the gRPC health probe along with your Docker image as shown following in the Dockerfile snippet:

RUN GRPC_HEALTH_PROBE_VERSION=v0.3.0 && 
    wget -qO/bin/grpc_health_probe 
    https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/
            ${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && 
    chmod +x /bin/grpc_health_probe

Then in the Kubernetes deployment’s pod specification, you can define livenessProbe and/or readinessProbe like this:

spec:
  containers:
  - name: server
    image: "kasunindrasiri/grpc-productinfo-server"
    ports:
    - containerPort: 50051
    readinessProbe:
      exec:
        command: ["/bin/grpc_health_probe", "-addr=:50051"] 1
      initialDelaySeconds: 5
    livenessProbe:
      exec:
        command: ["/bin/grpc_health_probe", "-addr=:50051"] 2
      initialDelaySeconds: 10
1

Specify grpc_health_probe as the readiness probe.

2

Specify grpc_health_probe as the liveness probe.

When you have liveness and readiness probes set using the gRPC health probe, then Kubernetes can make decisions based on the health of your gRPC server.

Other Ecosystem Projects

There are quite a few other ecosystem projects that can be useful when building gRPC-based applications. Customer protoc plugging is a similar ecosystem requirement where projects such as protoc-gen-star (PG*) started getting some traction. Also, libraries such as protoc-gen-validate (PGV) offer a protoc plug-in to generate polyglot message validators. The ecosystem has kept on growing with new projects for various requirements in gRPC application development.

With this, we conclude our discussion of the gRPC ecosystem components. It’s important to keep in mind that these ecosystem projects are not part of the gRPC project. You need to evaluate them properly prior to using them in production. Also, these are subject to change: some projects may become obsolete, others may become mainstream, and other, completely new projects, may emerge in the gRPC ecosystem.

Summary

As you can see, though gRPC ecosystem projects are not part of the core gRPC implementation, they can be quite useful in building and running gRPC applications for real-world use cases. These projects are built around gRPC to overcome problems or limitations encountered while building a production system using gRPC. For example, when we are moving our RESTful services to gRPC services, we need to consider our existing client who used to call our service in a RESTful manner. In order to overcome this issue, HTTP/JSON transcoding and gRPC gateway concepts are introduced, so that both existing RESTful clients and new gRPC clients can call the same service. Similarly, service reflection is introduced to overcome the limitation in testing gRPC services using a command-line tool.

Since gRPC is a very popular topic in the cloud-native world and developers are now gradually moving toward gRPC from REST services, we will see more projects like these built around gRPC in the future.

Congratulations! You have just completed reading gRPC: Up and Running, and have pretty much covered the entire development life cycle of the gRPC application along with numerous code examples based on Go and Java. We hope this book laid the foundation in the journey of using gRPC as an inter-process communication technology for your applications and microservices. What you learned in this book will help you to rapidly build gRPC applications, understand how they can coexist with other technologies, and run them in production.

So, it’s time to explore gRPC further. Try building real-world applications by applying the techniques that you learned in this book. There’s a significant amount of features of gRPC that are dependent on the programming language that you use to develop gRPC applications, so you will have to learn certain techniques that are specific to the language that you use. Also, the gRPC ecosystem is exponentially growing and it will be helpful to stay up to date on the latest technologies and frameworks that support gRPC. Go forth and explore!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset