grpc-gateway--支持grpc和restful

摘要:
}serviceEchoService{rpcEcho(StringMessage)return(StringMessage){option(google.api.http)={post:echopb/echopb/echo.protoprotocol Iechopb/--swagger_out=logtostderr=true:

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定义中的自定义选项生成的。

grpc-gateway--支持grpc和restful第1张

安装

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

grpc-gateway--支持grpc和restful第2张 

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版本的调试工具

免责声明:文章转载自《grpc-gateway--支持grpc和restful》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【转贴】mysql导入数据load data infile用法NPOI 添加下拉列表下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

VulnHub::Moee

实验环境 存在4个flag 渗透过程 0x01 信息搜集 GET IP 由于不知道靶机IP地址,进行D段扫描,获得靶机IP地址。 masscan扫描: masscan 192.168.2.0/24 -p80 --rate 1000 Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2020-12-05 0...

win下配置nginx

1.下载:http://nginx.org/en/download.html 2.在安装目录cmd: start nginx.exe 启动nginx 3.修改默认运行端口80(nginx.conf):  HTTP 数据分发 修改配置文件nginx.conf相应节点: 修改完后重启服务: nginx -s reload TCP 数据分发:  ng...

【Java】分割字符串并实现去重(重复的分割字符)

原始字符串:" Mem: 4194304 4134400 59904 0 0 2572228"需求:把原始字符串中的有效字符提取出来(有效字符指:非空白字符) 即预期为“Mem:”,“4194304”,“4134400”,“59904”,“0”,“0”,“2572228”这...

react antd中codemirror的基本使用

  codemirror是什么?   使用JavaScript为浏览器实现的多功能文本编辑器。   codemirror作用   专门用于编辑代码,并带有实现更高级编辑功能的多种语言模式和附加组件。   codemirror官网   https://codemirror.net/  (全英文,我这种英语渣渣是直接谷歌翻译的,大家不要学我)   https:...

el-table的多选框表头增加全选字样

实现效果: 实现方法: 在el-table-column中设置label属性并不会起作用,因此全选二字需要使用CSS来实现 .el-table__header .el-table-column--selection .cell .el-checkbox:after { color: #333; content: "全选"; font-size...

ECNUOJ 2147 字符环

字符环 Time Limit:1000MS Memory Limit:65536KBTotal Submit:562 Accepted:146 Description 字符环:就是将给定的一个字符串,首尾相连而形成的一个环。现在我们来玩一个有趣的两人游戏:每次甲给出两个字符串A和B,然后让乙判断字符串B是否能够被字符环A所包含.例如,A = aabcd ,...