feat: support google.api.http in gateway (#2161)

This commit is contained in:
Kevin Wan
2022-07-17 14:57:25 +08:00
committed by GitHub
parent 4324ddc024
commit 0dd2768d09
4 changed files with 94 additions and 10 deletions

View File

@@ -2,19 +2,29 @@ package internal
import (
"fmt"
"net/http"
"strings"
"github.com/fullstorydev/grpcurl"
"github.com/jhump/protoreflect/desc"
"google.golang.org/genproto/googleapis/api/annotations"
"google.golang.org/protobuf/proto"
)
type Method struct {
HttpMethod string
HttpPath string
RpcPath string
}
// GetMethods returns all methods of the given grpcurl.DescriptorSource.
func GetMethods(source grpcurl.DescriptorSource) ([]string, error) {
func GetMethods(source grpcurl.DescriptorSource) ([]Method, error) {
svcs, err := source.ListServices()
if err != nil {
return nil, err
}
var methods []string
var methods []Method
for _, svc := range svcs {
d, err := source.FindSymbol(svc)
if err != nil {
@@ -25,10 +35,68 @@ func GetMethods(source grpcurl.DescriptorSource) ([]string, error) {
case *desc.ServiceDescriptor:
svcMethods := val.GetMethods()
for _, method := range svcMethods {
methods = append(methods, fmt.Sprintf("%s/%s", svc, method.GetName()))
rpcPath := fmt.Sprintf("%s/%s", svc, method.GetName())
ext := proto.GetExtension(method.GetMethodOptions(), annotations.E_Http)
if ext == nil {
methods = append(methods, Method{
RpcPath: rpcPath,
})
continue
}
httpExt, ok := ext.(*annotations.HttpRule)
if !ok {
methods = append(methods, Method{
RpcPath: rpcPath,
})
continue
}
switch rule := httpExt.GetPattern().(type) {
case *annotations.HttpRule_Get:
methods = append(methods, Method{
HttpMethod: http.MethodGet,
HttpPath: adjustHttpPath(rule.Get),
RpcPath: rpcPath,
})
case *annotations.HttpRule_Post:
methods = append(methods, Method{
HttpMethod: http.MethodPost,
HttpPath: adjustHttpPath(rule.Post),
RpcPath: rpcPath,
})
case *annotations.HttpRule_Put:
methods = append(methods, Method{
HttpMethod: http.MethodPut,
HttpPath: adjustHttpPath(rule.Put),
RpcPath: rpcPath,
})
case *annotations.HttpRule_Delete:
methods = append(methods, Method{
HttpMethod: http.MethodDelete,
HttpPath: adjustHttpPath(rule.Delete),
RpcPath: rpcPath,
})
case *annotations.HttpRule_Patch:
methods = append(methods, Method{
HttpMethod: http.MethodPatch,
HttpPath: adjustHttpPath(rule.Patch),
RpcPath: rpcPath,
})
default:
methods = append(methods, Method{
RpcPath: rpcPath,
})
}
}
}
}
return methods, nil
}
func adjustHttpPath(path string) string {
path = strings.ReplaceAll(path, "{", ":")
path = strings.ReplaceAll(path, "}", "")
return path
}

View File

@@ -25,5 +25,9 @@ func TestGetMethods(t *testing.T) {
assert.Nil(t, err)
methods, err := GetMethods(source)
assert.Nil(t, err)
assert.EqualValues(t, []string{"hello.Hello/Ping"}, methods)
assert.EqualValues(t, []Method{
{
RpcPath: "hello.Hello/Ping",
},
}, methods)
}