Olá, Habr. Convidamos futuros alunos do curso "Arquiteto de Software" a participarem do webinar aberto sobre o tema "Idempotência e comutabilidade de API em filas e HTTP" .
Também compartilhamos a tradução de material útil.
Dentro da estrutura de uma arquitetura de microsserviço moderna, podemos dividir microsserviços em dois grupos principais, dependendo de seu relacionamento e interação. O primeiro grupo representa microsserviços externos que são diretamente acessíveis aos usuários. São principalmente APIs baseadas em HTTP que usam mensagens de texto simples (JSON, XML, etc.), otimizadas para uso por desenvolvedores terceirizados, usando Representative State Transfer (REST) como tecnologia de comunicação.
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
, , . 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.
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.
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, .
:
Generating Unified APIs with Protocol Buffers and gRPC
Writing REST Services for the gRPC curious
Using gRPC for Long-lived and Streaming RPCs
"Software Architect".
" API HTTP".