You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:50:26