• grpc-gateway--支持grpc和restful


    The grpc-gateway is a plugin of the Google protocol buffers compiler protoc. It reads protobuf service definitions and generates a reverse-proxy server which 'translates a RESTful HTTP API into gRPC. This server is generated according to the google.api.http annotations in your service definitions.

    grpc-gateway是protoc的一个插件。它读取gRPC服务定义,并生成一个反向代理服务器,将RESTful JSON API转换为gRPC。此服务器是根据gRPC定义中的自定义选项生成的。

    安装

    protoc:https://github.com/protocolbuffers/protobuf/releases

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

    简单示例

    https://github.com/grpc-ecosystem/grpc-gateway示例项目目录:

    .
    ├── cmd
    │   ├── echoclient
    │   │   └── client.go
    │   ├── echohttp
    │   │   └── httpserver.go
    │   └── echoserver
    │       └── server.go
    ├── echopb
    │   ├── echo.pb.go
    │   ├── echo.pb.gw.go
    │   ├── echo.proto
    │   ├── echo.swagger.json
    │   └── google
    │       ├── api
    │       │   ├── annotations.proto
    │       │   ├── httpbody.proto
    │       │   └── http.proto
    │       └── rpc
    │           ├── code.proto
    │           ├── error_details.proto
    │           └── status.proto
    ├── go.mod
    ├── go.sum

    echopb/google拷贝自grpc-gateway/third_party。

    echo.proto增加 a google.api.http annotation:

    syntax = "proto3";
    package echopb;
    
    import "google/api/annotations.proto";
    
    message StringMessage{
        string value = 1;
    }
    
    service EchoService{
        rpc Echo(StringMessage) returns (StringMessage){
            option (google.api.http) = { 
                post: "/v1/example/echo"
                body: "*" 
            };
        }   
    }

    echo.pb.go echo.pb.gw.go和echo.swagger.json都是工具生成的。

    protoc -I ./echopb/ --go_out=plugins=grpc:echopb echopb/echo.proto
    protoc -I echopb --grpc-gateway_out=logtostderr=true:echopb/ echopb/echo.proto
    protoc -I echopb/ --swagger_out=logtostderr=true:echopb/ echopb/echo.proto

    server.go,监听在localhost:8088

    package main
    
    import (
        "context"
        "log"
        "net"
    
        "google.golang.org/grpc"
        pb "example/echopb" 
    )
    
    const (
        port = ":8088"
    )
    
    type server struct{
        pb.UnimplementedEchoServiceServer
    } 
    
    func (s *server) Echo(ctx context.Context, req *pb.StringMessage) (*pb.StringMessage, error) {
        return &pb.StringMessage{Value: req.GetValue()}, nil 
    }
    
    func main(){
        lis, err := net.Listen("tcp", port)
        if err != nil {
            log.Fatalf("failed to listen: %v
    ", err)
        }   
    
        s := grpc.NewServer()
        pb.RegisterEchoServiceServer(s, &server{})
    
        if err := s.Serve(lis); err != nil {
            log.Fatalf("failed to serve: %v", err)
        }   
    }

    client.go

    package main
    
    import (
        "context"
        "log"
        "time"
    
        "google.golang.org/grpc"
        pb "example/echopb"
    )
    
    const (
        addr = "localhost:8088"
    )
    
    func main(){
        ctx, cancel := context.WithTimeout(context.Background(), time.Second)
        defer cancel()
    
        conn, err := grpc.DialContext(ctx, addr, grpc.WithBlock(), grpc.WithInsecure())
        if err != nil {
            log.Fatalf("did not connect: %v
    ", err)
        }   
        defer conn.Close()
        c := pb.NewEchoServiceClient(conn)
    
        log.Printf("echo request: wang
    ")
    
        r, err := c.Echo(ctx, &pb.StringMessage{Value: "wang"})
        if err != nil {
            log.Fatalf("could not echo: %v
    ", err)
        }   
    
        log.Printf("Echo reply: %s
    ", r.GetValue())
    }

    httpserver.go

    package main
    
    import (
        "context"
        "flag"
        "net/http"
    
        "github.com/golang/glog"
        "github.com/grpc-ecosystem/grpc-gateway/runtime"
        "google.golang.org/grpc"
    
        gw "example/echopb"
    )
    
    var (
        grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:8088", "gRPC server endpoint")
    )
    
    func run() error{
        ctx := context.Background()
        ctx, cancel := context.WithCancel(ctx)
        defer cancel()
    
        mux := runtime.NewServeMux()
        opts := []grpc.DialOption{grpc.WithInsecure()}
        err := gw.RegisterEchoServiceHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)
        if err != nil {
            return err 
        }   
    
        return http.ListenAndServe(":8081", mux)
    }
    
    func main(){
        flag.Parse()
        defer glog.Flush()
    
        if err := run(); err != nil {
            glog.Fatal(err)
        }   
    }

    可通过如下命令本地查看swagger接口:

    swagger serve --host=0.0.0.0 --port=9000 --no-open echopb/echo.swagger.json

    http://localhost:9000/docs    查看到POST地址: /v1/example/echo

    POST: curl -XPOST --data '{"value":"wangqing"}' http://localhost:8081/v1/example/echo

     

    openNESS应用

    eaa.proto:https://gitee.com/yuxio/specs/blob/master/schema/pb/eaa.proto

    syntax = "proto3";
    
    package openness.eaa;
    option go_package = "github.com/open-ness/eaa;eaa";
    
    import "google/protobuf/empty.proto";
    import "google/api/annotations.proto";
    import "protoc-gen-swagger/options/annotations.proto";

    生成swagger:

    protoc -I./pb -I../../ben-krieger/grpc-gateway -I../../ben-krieger/grpc-gateway/third_party/googleapis --swagger_out=allow_repeated_fields_in_body=true,logtostderr=true:eaa ./pb/eaa.proto

    参考:

    1. https://github.com/grpc-ecosystem/grpc-gateway  https://grpc-ecosystem.github.io/grpc-gateway/

    2. grpc-gateway应用 煎鱼  grpc + grpc gateway

    3. OpenNESS eaa.proto生成swagger yaml

    4. gRPC 调试工具 gRPC-swagger  java版本的调试工具

  • 相关阅读:
    iOS sandbox
    属性和成员变量
    SDWebImage
    MRC和ARC混编
    MRC转ARC(2)
    MRC转ARC
    CentOS7.x关闭防火墙
    Linux下Tomcat带日志启动命令
    SpringBoot-属性文件properties形式
    SpringBoot-配置Java方式
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/12733261.html
Copyright © 2020-2023  润新知