进阶
hello.protobuf文件 
syntax = "proto3";
package hello;
option go_package = "./hello";
// 这里增加 improt
import "google/api/annotations.proto";
message Request {
}
message Response {
  string msg = 1;
}
service Hello {
  rpc Ping(Request) returns(Response) {
    // 这里增加 option
    option (google.api.http) = {
      post: "/api/v1/hello"
      body: "*"
    };
  }
}
- 更新依赖
 
// 需要手动下载 annotations.protobuf 文件: https://github.com/googleapis/googleapis/tree/master/google/api 下载到对应的文件夹
-app
   -hello.proto
   -google
	-api
            -annotations.proto
            -http.proto
	-protobuf
            -descriptor.proto
- 继续下一步生成文件
$ 
goctl rpc protoc hello.proto --go_out=server --go-grpc_out=server --zrpc_out=server 
package main
import (
	"flag"
	"github.com/zeromicro/go-zero/core/conf"
	"github.com/zeromicro/go-zero/gateway"
)
var configFile = flag.String("f", "etc/gateway.yaml", "config file")
func main() {
	
	flag.Parse()
	var c gateway.GatewayConf
	conf.MustLoad(*configFile, &c)
	gw := gateway.MustNewServer(c, withHeaders())
	defer gw.Stop()
	// 注册错误处理
	httpx.SetErrorHandlerCtx(grpcErrorHandlerCtx)
	gw.Start()
}
// gateway header 会带上前缀 Grpc-Metadata-, 自定义处理方法, 去掉前缀
func withHeaders() func(*gateway.Server) {
	return gateway.WithHeaderProcessor(func(header http.Header) []string {
		var values []string
		// 这里使用 protobuf 定义枚举的 name 字符串作为 key
		for key, _ := range xxx.MetaDataRequiredKey_value {
			values = append(values, fmt.Sprintf("%s:%s", key, header.Get(key)))
		}
		return values
	})
}
// 自定义错误
func grpcErrorHandler(err error) (int, any) {
	if s, ok := status.FromError(err); ok {
		return http.StatusOK, Res{
			Code: int(s.Code()),
			Msg:  s.Message(),
		}
	}
	return http.StatusOK, Res{
		Code: http.StatusInternalServerError,
		Msg:  err.Error(),
	}
}
func grpcErrorHandlerCtx(ctx context.Context, err error) (int, any) {
	
	return grpcErrorHandler(err)
}
type Res struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
}
More
- 默认的
protobuf生成的定义是没有请求方法和请求路径的定义, 所以不会自动注册, 这里提了一个pr, 默认添加POST方法和rpc方法名字作为API的默认参数 
gateway传递header参数到rpc的时候需要带上前缀Grpc-Metadata-