The authentication method used in this article is two -way certification, which can also be changed to other authentication methods. For referenceGRPC tutorial -TLS unidirectional certification, two -way certification, token certification, interceptor For transformation, this article will not be repeated.
https://gitee.com/XiMuQi/go-grpc
After the ETCD3 API is fully upgraded to GRPC, it is also necessary to provide REST API services. It is not reasonable to maintain the two versions of services, sogrpc-gateway born. A gateway is realized by using the custom Option of Protobuf. The server can also turn on GRPC services and HTTP services at the same time. HTTP services are responsible for receiving client requests, and then transform the request information conversion of the Protobuf format as GRPC request data, and then send it to the GRPC service. HTTP service. The service et al. The service is returned to the client from the GRPC service obtaining response to the JSON data.
GRPC-Gateway is a plug-in for the Protocol Buffers compiler protocol. It reads the Protobuf service definition and generates a reverse proxy server. The server converts the RESTFUL HTTP API to GRPC. This service is based ongoogle.api.http annotationsThe annotation is generated, so the annotation will be used in the project.
When the request process, when the client sends the HTTP request, GRPC-Gateway accepts the request to generate the client of GRPC to request the Server end of GRPC; GRPC-Gateway actually does the role of reverse proxy. Therefore, two services will be generated, one is the HTTP service generated by GRPC-Gateway. It is responsible for receiving the client's HTTP request, a GRPC server service, responsible for handling the CLIENT request.

go get -u google.golang.org/protobuf/cmd/protoc-gen-go
go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc
go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2

In 1.2, we talk about needgoogle/api/annotations.protoTherefore, you need to put these files in the project, and after the previous environment configuration is completed, the project is availableExternal Libraries Copy all the content under Google bags in the GRPC-Gateway package to a separate directory of the project, pay attention tov1.16.0Under the version,v2.10.2No.
Figure 1

Figure II

Will google The folder is placedpbfiles Down:

NewProdGrpcGateWay.proto In the PBFiles directory, it is the same level as Google. some Interpretation documentation CreatedProd.proto In fact, they are all the same, but there will be a small problem in this project. It may be reported when running later:
{"code":12, "message":"method GetProdStock not implemented", "details":[]}
The reason for this problem is that it is integrated in this projectGRPC tutorial -TLS unidirectional certification, two -way certification, token certification, interceptor The code, may appear in multiple examplesprotobuf When the content of the file is the same, it is possible to implement in other example interfaces when implementing the getprodStock method, so report this error.
Solution
1. ModifyProd.protoThe method name in the inside; (this article uses the method)
2. One project alone;
ProdGrpcGateWay.proto content:
syntax = "proto3"; // Proto3's grammar, without writing, it will default
package services; // Bag name, use the Go file through protoc to generate GO files
option go_package = "../service"; // Add the path to generate GO files
// Must be imported
import "google/api/annotations.proto";
message GrpcGateWayRequest {
int32 goods_id = 1; // The product ID passed in
}
message GrpcGateWayResponse {
int32 goods_stock =1; //Commodity stocks
}
service GrpcGateWayService {
rpc GetGrpcGateWayStock (GrpcGateWayRequest) returns (GrpcGateWayResponse){
option (google.api.http) = {
get: "/v1/prod/{goods_id}" // Note that the path parameters here should be consistent with the definition defined in GrpcgatewayRequest above
};
}
}
ProdGrpcGateWay.proto Convert to related Go filesExecute the following commands in the PBFILES directory, be careful not to write wrong!
ProdGrpcGateWay.pb.go、ProdGrpcGateWay_grpc.pb.go The command:protoc --go_out=. --go-grpc_out=. *.proto
ProdGrpcGateWay.pb.gw.go Order:protoc --grpc-gateway_out=logtostderr=true:../service ProdGrpcGateWay.proto
Copy one copy in the two -way certification example. This article is copied tokeys2 Below, the explanation of generating related certificates can be seen in the relevant links in the preface.
server.go
package main
import (
"context"
"crypto/tls"
"crypto/x509"
"go-grpc/grpc-gateway/service"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/grpclog"
"io/ioutil"
"log"
"net"
)
const (
// Address GRPC service address
ServerAddress = "127.0.0.1:8888"
)
// 1, declare a server, inside is an unrealized field
type server struct {
service.UnimplementedGrpcGateWayServiceServer
}
// 2. It must be realized in the remote call interface declared in the productgrpcgateway.proto, otherwise the client will report:
//rpc error: code = Unimplemented desc = method GetGrpcGateWayStock not implemente
func (s *server) GetGrpcGateWayStock(ctx context.Context, in *service.GrpcGateWayRequest) (*service.GrpcGateWayResponse, error) {
return &service.GrpcGateWayResponse{GoodsStock: in.GetGoodsId()}, nil
}
func main() {
// 1. Create a server with CA certificate verification
rpcServer := grpc.NewServer(grpc.Creds(GetServeCreds()))
// 2. Registration service
service.RegisterGrpcGateWayServiceServer(rpcServer, &server{})
// 3. Set the transmission protocol and monitoring address
listen, err := net.Listen("tcp", ServerAddress)
if err != nil {
log.Fatal("Listening port failed", err)
}
log.Println("Server listen on " + ServerAddress + " with TLS")
// 4. Start the service
rpcServer.Serve(listen)
}
// Add to server certification
func GetServeCreds() credentials.TransportCredentials {
// TLS certification
// Read and analyze the information from the document -related documents, get the certificate of the certificate, the key pair
cert, err := tls.LoadX509KeyPair("grpc-gateway/keys2/server.pem", "grpc-gateway/keys2/server.key")
if err != nil {
grpclog.Fatalf("Failed to find server credentials %v", err)
}
certPool := x509.NewCertPool() // Initialize a Certpool
ca, err := ioutil.ReadFile("grpc-gateway/keys2/ca.pem")
if err != nil {
grpclog.Fatalf("Failed to find root credentials %v", err)
}
certPool.AppendCertsFromPEM(ca) // Analyze the certificate that is introduced, and the resolution will be successfully added to the pool
creds := credentials.NewTLS(&tls.Config{ // Build TLS -based TransportCRedentials option
Certificates: []tls.Certificate{cert}, // The server certificate chain, there can be multiple
ClientAuth: tls.RequireAndVerifyClientCert, // Requires to verify the client certificate
ClientCAs: certPool, // Set the collection of the root certificate, and use the pattern set in clientAuth
})
return creds
}
clientServer.go
package main
import (
"context"
"crypto/tls"
"crypto/x509"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"go-grpc/grpc-gateway/service"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/grpclog"
"io/ioutil"
"log"
"net/http"
)
const (
// Serveraddress GRPC service address
ServerAddress = "127.0.0.1:8888"
// ClientAddress is the address of the browser and other when sending HTTP requests
ClientAddress = "127.0.0.1:8080"
)
func main() {
ctx := context.Background()
ctx, cancelFunc := context.WithCancel(ctx)
defer cancelFunc()
// 1. Create routes
mux := runtime.NewServeMux()
// 2. Join the certification
opt := []grpc.DialOption{grpc.WithTransportCredentials(GetClientCreds())}
// 3. The method of registering the request server
err := service.RegisterGrpcGateWayServiceHandlerFromEndpoint(ctx, mux, ServerAddress, opt)
if err != nil {
log.Fatalf("cannot start grpc gateway: %v", err)
}
// 4. Start and monitor http requests
err = http.ListenAndServe(ClientAddress, mux)
if err != nil {
log.Fatalf("cannot listen and server: %v", err)
}
log.Println("ClientServer listen on " + ServerAddress + " with TLS")
}
// Join the client certification certificate
func GetClientCreds() credentials.TransportCredentials {
// TLS connection
// Read and analyze the information from the document -related documents, get the certificate of the certificate, the key pair
cert, err := tls.LoadX509KeyPair("grpc-gateway/keys2/client.pem", "grpc-gateway/keys2/client.key")
if err != nil {
grpclog.Fatalf("Failed to find client credentials %v", err)
}
certPool := x509.NewCertPool()
ca, err := ioutil.ReadFile("grpc-gateway/keys2/ca.pem")
if err != nil {
grpclog.Fatalf("Failed to find root credentials %v", err)
}
certPool.AppendCertsFromPEM(ca)
creds := credentials.NewTLS(&tls.Config{
Certificates: []tls.Certificate{cert}, // Client certificate
ServerName: "ximu.info", // Note that the parameters here are the serverName allowed in the configuration file, which is the DNS configured in it ...
RootCAs: certPool,
})
return creds
}
Attached::client.go(Whether the test and server communication is normal)
package main
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"go-grpc/grpc-gateway/service"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"io/ioutil"
"log"
)
const (
// Address GRPC service address
Address = "127.0.0.1:8888"
)
func main() {
// Certificate certification-two-way certification
// Read and analyze the information from the document -related documents, get the certificate of the certificate, the key pair
cert, _ := tls.LoadX509KeyPair("grpc-gateway/keys2/client.pem", "grpc-gateway/keys2/client.key")
// Create a new, empty Certpool
certPool := x509.NewCertPool()
ca, _ := ioutil.ReadFile("grpc-gateway/keys2/ca.pem")
// Note that only the root certificate of PEM type can be parsed here, so what is needed is CA.PEM
// Try to analyze the certificate of PEM encoding. If the analysis is successful, it will be added to the Certpool to facilitate the later use
certPool.AppendCertsFromPEM(ca)
// Build TLS -based TransportCRedentials option
creds := credentials.NewTLS(&tls.Config{
// Set the certificate chain, allowing one or more
Certificates: []tls.Certificate{cert},
ServerName: "ximu.info", // Note that the parameters here are the serverName allowed in the configuration file, which is the DNS configured in it ...
RootCAs: certPool,
})
// 1. Establish a connection
conn, err := grpc.Dial(Address, grpc.WithTransportCredentials(creds))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
request := &service.GrpcGateWayRequest{
GoodsId: 123,
}
// 2. Call the newGrpcgatewayServiceClient method in the product
query := service.NewGrpcGateWayServiceClient(conn)
// 3. Call the RPC method
res, err := query.GetGrpcGateWayStock(context.Background(), request)
if err != nil {
log.Fatal("Call the GRPC method error:", err)
}
fmt.Println("GRPC-Gateway: The successful GRPC method is successful, goodsstock =", res)
}
Start firstserver.go, Start againclientServer.go
http://localhost:8080/v1/prod/25

1 Introduction GRPC Transcoding is a conversion rule that defines GRPC and HTTP REST API. This rule applies to Google APIs, Cloud Endpoints, GRPC Gateway, etc., is currently widely used. English docum...
Original is not easy, do not reprint without permission. Article catalog First, the use of GRPC 1.1 GPRC and Protobuf installation 1.2 Write a Proto file 1.3 Writing a server interface program 1.4 Wri...
In fact grpc middleware and middleware, like writing http http service Processor: Handler definition http service, the most important is the processor: Handler, an interface we need to define a proces...
GRPC is a high-performance RPC (REMOTE Procedure Call) of Google, which has the following advantages: Provide efficient process communication. GRPC does not use XML or JSON this text format, but uses ...
GRPC-Gateway learning notes Introduction Install I can't find the "Google / API / Annotations.proto" file Pile code generation command Introduction grpc-gatewayCan be very convenientgrpcInte...
Original portal: The default go successfully installed First step Create a folder The second step Step 3 Clone someone else's repository from GitHub Step 4 Installation carry out...
1 RPC framework principleThe goal of the RPC framework is to make remote service calls simpler and more transparent. The RPC framework is responsible for shielding the underlying transmission mode (TC...
I have written a tutorial on sending and receiving messages using gRPC in Python before, you can refer to the article"Those who experience gRPC". I recently planned to use gRPC in a C++ proj...
Condition operators are the only in C languageTriple computing symbolThe basic form is:expr1?expr2:expr3,One condition operator requires it requires three expressions。 1. Operation rules for condition...
chown Command in English: change file ownership Path where the command is located: /bin/chown Execution permission: root Syntax: chown [user] [file or directory] Functional Description: Change the own...