grpc-gateway创建失败:JSONPb字段EnumsAsInts、OrigName识别异常
问题:grpc-gateway中runtime.JSONPb字段提示未知字段
问题详情
启动grpc-gateway时,设置runtime.JSONPb的EnumsAsInts和OrigName字段,编译器提示这两个字段未知,但查看jsonp/encode.go文件时确实存在这些字段。相关代码、编译错误及依赖配置如下:
代码示例
import ( "context" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" "log" "net/http" authpb "seekCar/auth/api/gen/v1" // protobuf生成的auth代码 ) func main() { c := context.Background() c, cancel := context.WithCancel(c) defer cancel() mux := runtime.NewServeMux(runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ EnumsAsInts: true, // Unknown field 'EnumsAsInts' in struct literal OrigName: true, // Unknown field 'OrigName' in struct literal })) err := authpb.RegisterAuthServiceHandlerFromEndpoint( c, mux, "localhost:8081", []grpc.DialOption{grpc.WithInsecure()}, ) if err != nil { log.Fatalf("cannot register auth service: %v", err) } log.Fatal(http.ListenAndServe(":8080", mux)) }
编译错误
Unknown field 'EnumsAsInts' in struct literal Unknown field 'OrigName' in struct literal
go.mod配置
module learnGo go 1.18 require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 go.uber.org/zap v1.16.0 google.golang.org/grpc v1.49.0 google.golang.org/protobuf v1.28.1 ) require ( github.com/golang/protobuf v1.5.2 // indirect github.com/pkg/errors v0.9.1 // indirect go.uber.org/atomic v1.6.0 // indirect go.uber.org/multierr v1.5.0 // indirect golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/genproto v0.0.0-20220930163606-c98284e70a91 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect )
问题原因
你使用的grpc-gateway v2.11.3版本,其runtime.JSONPb结构体已切换为封装google.golang.org/protobuf/encoding/protojson的MarshalOptions和UnmarshalOptions,而非旧版github.com/golang/protobuf/jsonpb的Marshaler。两个包的结构体字段名存在差异:
- 旧版
jsonpb.Marshaler的EnumsAsInts对应新版protojson.MarshalOptions的UseEnumNumbers - 旧版
jsonpb.Marshaler的OrigName对应新版protojson.MarshalOptions的UseProtoNames
你查看的jsonp/encode.go属于旧版包,和当前grpc-gateway依赖的新版包不匹配,因此编译器报错。
修复方案
修改代码中的字段名,替换为新版protojson对应的字段即可:
import ( // 新增导入protojson包 "google.golang.org/protobuf/encoding/protojson" // 其他导入保持不变 "context" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "google.golang.org/grpc" "log" "net/http" authpb "seekCar/auth/api/gen/v1" ) func main() { c := context.Background() c, cancel := context.WithCancel(c) defer cancel() mux := runtime.NewServeMux(runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ MarshalOptions: protojson.MarshalOptions{ UseEnumNumbers: true, // 替代原EnumsAsInts UseProtoNames: true, // 替代原OrigName }, })) // 后续代码保持不变 err := authpb.RegisterAuthServiceHandlerFromEndpoint( c, mux, "localhost:8081", []grpc.DialOption{grpc.WithInsecure()}, ) if err != nil { log.Fatalf("cannot register auth service: %v", err) } log.Fatal(http.ListenAndServe(":8080", mux)) }
如果坚持要使用旧版字段名,可以将grpc-gateway降级到v2.7.x及更早版本(这些版本仍依赖旧版jsonpb包),但官方已标记旧版包为废弃,不推荐此方案。
内容的提问来源于stack exchange,提问作者Up Pu
相关产品推荐
相关产品推荐

