Skip to content

Commit 4f166c9

Browse files
committed
feat(transport/http/binding): add option to control using proto text name as key during URL encoding
1 parent 084c8b4 commit 4f166c9

File tree

19 files changed

+221
-83
lines changed

19 files changed

+221
-83
lines changed

Diff for: api/metadata/metadata.pb.go

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: api/metadata/metadata_grpc.pb.go

+11-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: api/metadata/metadata_http.pb.go

+18-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: cmd/protoc-gen-go-http/http.go

+16-14
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ import (
77
"regexp"
88
"strings"
99

10-
"google.golang.org/protobuf/reflect/protoreflect"
11-
1210
"google.golang.org/genproto/googleapis/api/annotations"
1311
"google.golang.org/protobuf/compiler/protogen"
1412
"google.golang.org/protobuf/proto"
13+
"google.golang.org/protobuf/reflect/protoreflect"
1514
"google.golang.org/protobuf/types/descriptorpb"
1615
)
1716

1817
const (
19-
contextPackage = protogen.GoImportPath("context")
20-
transportHTTPPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http")
21-
bindingPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http/binding")
18+
contextPackage = protogen.GoImportPath("context")
19+
transportHTTPPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http")
20+
bindingPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/transport/http/binding")
21+
formEncodeOptionPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/encoding/form/option")
2222
)
2323

2424
var methodSets = make(map[string]int)
@@ -55,6 +55,7 @@ func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.
5555
g.P("// is compatible with the kratos package it is being compiled against.")
5656
g.P("var _ = new(", contextPackage.Ident("Context"), ")")
5757
g.P("var _ = ", bindingPackage.Ident("EncodeURL"))
58+
g.P("var _ = ", formEncodeOptionPackage.Ident("Encode"))
5859
g.P("const _ = ", transportHTTPPackage.Ident("SupportPackageIsVersion1"))
5960
g.P()
6061

@@ -209,15 +210,16 @@ func buildMethodDesc(g *protogen.GeneratedFile, m *protogen.Method, method, path
209210
comment = "// " + m.GoName + strings.TrimPrefix(strings.TrimSuffix(comment, "\n"), "//")
210211
}
211212
return &methodDesc{
212-
Name: m.GoName,
213-
OriginalName: string(m.Desc.Name()),
214-
Num: methodSets[m.GoName],
215-
Request: g.QualifiedGoIdent(m.Input.GoIdent),
216-
Reply: g.QualifiedGoIdent(m.Output.GoIdent),
217-
Comment: comment,
218-
Path: path,
219-
Method: method,
220-
HasVars: len(vars) > 0,
213+
Name: m.GoName,
214+
OriginalName: string(m.Desc.Name()),
215+
Num: methodSets[m.GoName],
216+
Request: g.QualifiedGoIdent(m.Input.GoIdent),
217+
Reply: g.QualifiedGoIdent(m.Output.GoIdent),
218+
Comment: comment,
219+
Path: path,
220+
Method: method,
221+
HasVars: len(vars) > 0,
222+
UseProtoTextEncodeURL: *isUseProtoTextEncodeURL,
221223
}
222224
}
223225

Diff for: cmd/protoc-gen-go-http/httpTemplate.tpl

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func New{{.ServiceType}}HTTPClient (client *http.Client) {{.ServiceType}}HTTPCli
7070
func (c *{{$svrType}}HTTPClientImpl) {{.Name}}(ctx context.Context, in *{{.Request}}, opts ...http.CallOption) (*{{.Reply}}, error) {
7171
var out {{.Reply}}
7272
pattern := "{{.Path}}"
73-
path := binding.EncodeURL(pattern, in, {{not .HasBody}})
73+
path := binding.EncodeURL(pattern, in, {{not .HasBody}}, option.Encode().UseProtoTextAsKey({{.UseProtoTextEncodeURL}}))
7474
opts = append(opts, http.Operation(Operation{{$svrType}}{{.OriginalName}}))
7575
opts = append(opts, http.PathTemplate(pattern))
7676
{{if .HasBody -}}

Diff for: cmd/protoc-gen-go-http/main.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import (
99
)
1010

1111
var (
12-
showVersion = flag.Bool("version", false, "print the version and exit")
13-
omitempty = flag.Bool("omitempty", true, "omit if google.api is empty")
14-
omitemptyPrefix = flag.String("omitempty_prefix", "", "omit if google.api is empty")
12+
showVersion = flag.Bool("version", false, "print the version and exit")
13+
omitempty = flag.Bool("omitempty", true, "omit if google.api is empty")
14+
omitemptyPrefix = flag.String("omitempty_prefix", "", "omit if google.api is empty")
15+
isUseProtoTextEncodeURL = flag.Bool("prototext_encodeurl", false, "use proto text name as params form key")
1516
)
1617

1718
func main() {

Diff for: cmd/protoc-gen-go-http/template.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@ type methodDesc struct {
2727
Reply string
2828
Comment string
2929
// http_rule
30-
Path string
31-
Method string
32-
HasVars bool
33-
HasBody bool
34-
Body string
35-
ResponseBody string
30+
Path string
31+
Method string
32+
HasVars bool
33+
HasBody bool
34+
Body string
35+
ResponseBody string
36+
UseProtoTextEncodeURL bool
3637
}
3738

3839
func (s *serviceDesc) execute() string {

Diff for: encoding/form/form.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ var (
2727
var tagName = "json"
2828

2929
func init() {
30-
decoder.SetTagName(tagName)
3130
encoder.SetTagName(tagName)
31+
decoder.SetTagName(tagName)
3232
encoding.RegisterCodec(codec{encoder: encoder, decoder: decoder})
3333
}
3434

Diff for: encoding/form/form_test.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"google.golang.org/protobuf/types/known/wrapperspb"
1313

1414
"github.com/go-kratos/kratos/v2/encoding"
15+
"github.com/go-kratos/kratos/v2/encoding/form/option"
1516
bdtest "github.com/go-kratos/kratos/v2/internal/testdata/binding"
1617
"github.com/go-kratos/kratos/v2/internal/testdata/complex"
1718
ectest "github.com/go-kratos/kratos/v2/internal/testdata/encoding"
@@ -264,7 +265,12 @@ func TestEncodeFieldMask(t *testing.T) {
264265
req := &bdtest.HelloRequest{
265266
UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"foo", "bar"}},
266267
}
267-
if v := EncodeFieldMask(req.ProtoReflect()); v != "updateMask=foo,bar" {
268+
v := EncodeFieldMask(req.ProtoReflect())
269+
if v != "updateMask=foo,bar" {
270+
t.Errorf("got %s", v)
271+
}
272+
v = EncodeFieldMask(req.ProtoReflect(), option.Encode().UseProtoTextAsKey(true))
273+
if v != "update_mask=foo,bar" {
268274
t.Errorf("got %s", v)
269275
}
270276
}
@@ -280,4 +286,9 @@ func TestOptional(t *testing.T) {
280286
if query.Encode() != "name=foo&optInt32=100&sub.naming=bar" {
281287
t.Fatalf("got %s", query.Encode())
282288
}
289+
290+
query, _ = EncodeValues(req, option.Encode().UseProtoTextAsKey(true))
291+
if query.Encode() != "name=foo&opt_int32=100&sub.naming=bar" {
292+
t.Fatalf("got %s", query.Encode())
293+
}
283294
}

Diff for: encoding/form/option/encode.go

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package option
2+
3+
// EncodeOption is the encoding options.
4+
type EncodeOption struct {
5+
ForceProtoTextAsKey bool // forces to use proto field text name.
6+
}
7+
8+
// Encode creates a new EncodeOption instance.
9+
func Encode() *EncodeOption {
10+
return &EncodeOption{}
11+
}
12+
13+
// UseProtoTextAsKey forces to use proto field text name as key.
14+
func (opt *EncodeOption) UseProtoTextAsKey(isUse bool) *EncodeOption {
15+
opt.ForceProtoTextAsKey = isUse
16+
return opt
17+
}
18+
19+
// MergeEncodeOptions merges the options.
20+
func MergeEncodeOptions(opts ...*EncodeOption) *EncodeOption {
21+
opt := new(EncodeOption)
22+
for _, o := range opts {
23+
if o == nil {
24+
continue
25+
}
26+
27+
if o.ForceProtoTextAsKey {
28+
opt.ForceProtoTextAsKey = true
29+
}
30+
}
31+
return opt
32+
}

Diff for: encoding/form/option/encode_test.go

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package option
2+
3+
import "testing"
4+
5+
func TestEncodeOption_UseProtoTextAsKey(t *testing.T) {
6+
e := Encode().UseProtoTextAsKey(true)
7+
if e.ForceProtoTextAsKey != true {
8+
t.Error("expect true")
9+
}
10+
e = Encode().UseProtoTextAsKey(false)
11+
if e.ForceProtoTextAsKey != false {
12+
t.Error("expect false")
13+
}
14+
}
15+
16+
func TestMergeEncodeOptions(t *testing.T) {
17+
opt := MergeEncodeOptions(nil)
18+
if opt == nil {
19+
t.Fatal("expect not nil")
20+
}
21+
if opt.ForceProtoTextAsKey {
22+
t.Error("expect false")
23+
}
24+
25+
opt = MergeEncodeOptions(Encode().UseProtoTextAsKey(true))
26+
if opt == nil {
27+
t.Fatal("expect not nil")
28+
}
29+
if !opt.ForceProtoTextAsKey {
30+
t.Error("expect true")
31+
}
32+
33+
opt = MergeEncodeOptions(&EncodeOption{}, Encode().UseProtoTextAsKey(true))
34+
if opt == nil {
35+
t.Fatal("expect not nil")
36+
}
37+
if !opt.ForceProtoTextAsKey {
38+
t.Error("expect true")
39+
}
40+
}

0 commit comments

Comments
 (0)