Building high-performance microservices with gRPC, Ballerina and Go

Hi, Habr. We invite future students of the "Software Architect" course to take part in an open webinar on the topic "Idempotency and commutability of API in queues and HTTP" .



We also share the translation of useful material.














. , . API HTTP, (JSON, XML . .), , (REST) ​​ . 





REST . OpenAPI , , REST API. API API, , , -. REST API HTTP GraphQL, .





— , . . , . REST API HTTP, . , , gRPC, .





gRPC?

gRPC — API (Remote procedure call — RPC) . RPC, , . , Thrift Avro, gRPC (interface description language — IDL). gRPC HTTP/2 — , gRPC REST HTTP/1.1. 





gRPC Protocol Buffers, , . , , () Protocol Buffers, .





gRPC

Figure 1. Microservices architecture segment of an online retail store
1. -

, , . 1 - , Ballerina Golang, , -. gRPC , , . 









syntax="proto3";
 
package retail_shop;
 
service OrderService {
   rpc UpdateOrder(Item) returns (Order);
}  
message Item {
   string itemNumber = 1;
   int32 quantity = 2;
}
message Order {
   string itemNumber = 1;
   int32 totalQuantity = 2;
   float subTotal = 3;
      
      



1. Order (order.proto)





Order . gRPC Ballerina gRPC / . 





$ ballerina grpc --mode service --input proto/order.proto --output gen_code
      
      







import ballerina/grpc;
listener grpc:Listener ep = new (9090);
 
service OrderService on ep {
   resource function UpdateOrder(grpc:Caller caller, Item value) {
       // Implementation goes here.
 
       // You should return an Order
   }
}
public type Order record {|
   string itemNumber = "";
   int totalQuantity = 0;
   float subTotal = 0.0;
  
|};
public type Item record {|
   string itemNumber = "";
   int quantity = 0;
  
|}; 
      
      



2. (OrderServicesampleservice.bal).





gRPC ​​ service



Ballerina, gRPC rpc ​​ resource function



Ballerina, gRPC — record







Order Ballerina OrderService gRPC





OrderService Cart. Ballerina.





$ ballerina grpc --mode client --input proto/order.proto --output gen_code
      
      



, . , gRPC gRPC.





public remote function UpdateOrder(Item req, grpc:Headers? headers = ()) returns ([Order, grpc:Headers]|grpc:Error) {
      
       var payload = check self.grpcClient->blockingExecute("retail_shop.OrderService/UpdateOrder", req, headers);
       grpc:Headers resHeaders = new;
       anydata result = ();
       [result, resHeaders] = payload;
       return [<Order>result, resHeaders];
   }
};
      
      



3.





Ballerina gRPC, , UpdateOrder



.





Checkout , , Cart. stream Order



.





syntax="proto3";
package retail_shop;
 
service CheckoutService {
   rpc Checkout(stream Order) returns (FinalBill) {}
}
message Order {
   string itemNumber = 1;
   int32 totalQuantity = 2;
   float subTotal = 3;
}
message FinalBill {
   float total = 1;
}
      
      



4. Checkout (checkout.proto)





checkout.proto



, ballerina grpc



.





$ ballerina grpc --mode service --input proto/checkout.proto --output gencode





gRPC

Cart () , , , . :





service CheckoutService on ep {
   resource function Checkout(grpc:Caller caller, stream<Order,error> clientStream) {
       float totalBill = 0;
 
       //Iterating through streamed messages here
       error? e = clientStream.forEach(function(Order order) {
           totalBill += order.subTotal;           
       });
       //Once the client completes stream, a grpc:EOS error is returned to indicate it
       if (e is grpc:EOS) {
           FinalBill finalBill = {
               total:totalBill
           };
           //Sending the total bill to the client
           grpc:Error? result = caller->send(finalBill);
           if (result is grpc:Error) {
               log:printError("Error occurred when sending the Finalbill: " + 
result.message() + " - " + <string>result.detail()["message"]);
           } else {
               log:printInfo ("Sending Final Bill Total: " + 
finalBill.total.toString());
           }
           result = caller->complete();
           if (result is grpc:Error) {
               log:printError("Error occurred when closing the connection: " + 
result.message() +" - " + <string>result.detail()["message"]);
           }
       }
       //If the client sends an error instead it can be handled here
       else if (e is grpc:Error) {
           log:printError("An unexpected error occured: " + e.message() + " - " +
                                                   <string>e.detail()["message"]);
       }   
   }
}
      
      



5. Service   CheckoutService



(CheckoutServicesampleservice.bal)





grpc:EOS



, , ( ) caller object



.





CheckoutService :





$ ballerina grpc --mode client --input proto/checkout.proto --output gencode
      
      



Cart. Cart REST API: , — . , gRPC Order . Checkout , , Checkout gRPC . Ballerina Stream Client Object



gRPC. 2 , Ballerina.





Figure 2. Streaming gRPC Ballerina client 
2. gRPC Ballerina 

CheckoutService resource function checkout Cart. , gRPC Stock, Golang, , .





syntax="proto3";
package retail_shop;
option go_package = "../stock;gen";
import "google/api/annotations.proto";
 
service StockService {
   rpc UpdateStock(UpdateStockRequest) returns (Stock) {
       option (google.api.http) = {
           // Route to this method from POST requests to /api/v1/stock
           put: "/api/v1/stock"
           body: "*"
       };
   }
}
message UpdateStockRequest {
   string itemNumber = 1;
   int32 quantity = 2;
}
message Stock {
   string itemNumber = 1;
   int32 quantity = 2;
      
      



6. Stock (stock.proto)





UpdateStock REST API API, gRPC . grpc-gateway — protoc, gRPC -, RESTful JSON API gRPC. 





 





Figure 3: grpc-gateway
3: grpc-gateway

grpc-gateway API- gRPC REST.





gRPC Golang:





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



grpc-gateway Golang:





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



stock.swagger.json:





protoc -I/usr/local/include -I. \
-I$GOROOT/src \
-I$GOROOT/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
-I$GOROOT/src \
--swagger_out=logtostderr=true:../stock/gen/. \
./stock.proto
      
      



git microservices-with-grpc README.md.





gRPC , . gRPC , , . , gRPC , REST API, , grpc-gateway. , , gRPC, Deadlines, Cancellation, Channels xDS, .





Ballerina gRPC, :





  • Unary Blocking





  • Unary Non-Blocking





  • Server Streaming





  • Client Streaming





  • Bidirectional Streaming





Golang gRPC, , , , Interceptor, Deadlines, Cancellation, Channels gRPC , . git grpc-go, .





:






"Software Architect".



" API HTTP".












All Articles