GRPC Tutorial-GRPC-Gateway

tags: gRPC  Golang  gateway  rpc  

Foreword

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.

Code

https://gitee.com/XiMuQi/go-grpc

1. GRPC gateway introduction

1.1 cause

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.

1.2 Supplement

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.

1.3 Process

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.

1.4 flowchart

Second, environmental configuration

2.1 Dependencies required

2.1.1 Proto to GO

go get -u google.golang.org/protobuf/cmd/protoc-gen-go 

2.1.2 grpc

go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc

2.1.3 grpc-gateway

go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway

2.1.4 API dependence on the service provided by the client

go get -u github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2

2.2 Download results

Three, code

3.1 Add Google/API/Annotations.proto

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

3.2 Location and entire project structure in the code

Will google The folder is placedpbfiles Down:

3.3 Create Protobuf Files

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.proto The 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
        };
    }
}

3.4ProdGrpcGateWay.proto Convert to related Go files

Execute the following commands in the PBFILES directory, be careful not to write wrong!

3.4.1 generationProdGrpcGateWay.pb.goProdGrpcGateWay_grpc.pb.go The command:

protoc --go_out=. --go-grpc_out=. *.proto

3.4.2 Generate GRPC-GatewayProdGrpcGateWay.pb.gw.go Order:

protoc --grpc-gateway_out=logtostderr=true:../service ProdGrpcGateWay.proto

3.5 Add certification

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.

3.6 server code

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
}

3.7 Client service code

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)

}

Fourth, test

4.1 Starting service

Start firstserver.go, Start againclientServer.go

4.2 Interface to access the clientserver service

http://localhost:8080/v1/prod/25

4.3 Test results

Intelligent Recommendation

GRPC-Gateway Transforming GRPC and HTTP API Rules

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...

The use of GRPC and GRPC-GATeway and the pit encountered

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...

GRPC development (9) -grpc service development -grpc-gateway middleware

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...

The simplest GRPC tutorial - 1 new GRPC

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 ...

[GO] GRPC-Gateway learning notes

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...

More Recommendation

Install grpc tutorial

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...

grpc java basic tutorial

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...

gRPC C++ Introduction Tutorial

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...

C Language Basics 48 Articles_15_ conditional operator (EXPR1? Expr2: Expr3, ternary computing symbols, ||, etc. are dual operators)

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...

18-chown command

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...

Copyright  DMCA © 2018-2026 - All Rights Reserved - www.programmersought.com  User Notice

Top