fix(grpc-gateway): support application/json and wildcard marshaler in ServeMux#39
Conversation
演练此pull request对.gitignore文件和gRPC Gateway的mux配置进行了更改。在.gitignore中添加了test_marshaler.go条目,在mux.go中为JSON和JSONPb添加了新的marshaler配置选项,包括默认的MIME通配符处理。 变更
代码审查工作量评估🎯 2 (简单) | ⏱️ ~10 分钟 诗
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip Migrating from UI to YAML configuration.Use the |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
api/grpc_gateway/mux.go (1)
26-54: 建议提取共享的 marshaler 配置以减少重复代码。三个 marshaler 使用完全相同的
MarshalOptions和UnmarshalOptions配置,可以提取为共享变量以提高可维护性。♻️ 重构建议:提取共享配置
+var defaultJSONPb = &runtime.JSONPb{ + MarshalOptions: protojson.MarshalOptions{ + EmitUnpopulated: true, + UseProtoNames: true, + }, + UnmarshalOptions: protojson.UnmarshalOptions{ + DiscardUnknown: false, + }, +} + var DefaultServeMuxOption = []runtime.ServeMuxOption{ runtime.WithErrorHandler(DefaultErrorHandler), runtime.WithRoutingErrorHandler(DefaultRoutingErrorHandler), runtime.WithIncomingHeaderMatcher(DefaultHeaderWarp), // 标准 JSON 格式 - runtime.WithMarshalerOption("application/json", &runtime.JSONPb{ - MarshalOptions: protojson.MarshalOptions{ - EmitUnpopulated: true, - UseProtoNames: true, - }, - UnmarshalOptions: protojson.UnmarshalOptions{ - DiscardUnknown: false, - }, - }), + runtime.WithMarshalerOption("application/json", defaultJSONPb), // Protobuf JSON 格式 - runtime.WithMarshalerOption("application/jsonpb", &runtime.JSONPb{ - MarshalOptions: protojson.MarshalOptions{ - EmitUnpopulated: true, - UseProtoNames: true, - }, - UnmarshalOptions: protojson.UnmarshalOptions{ - DiscardUnknown: false, - }, - }), + runtime.WithMarshalerOption("application/jsonpb", defaultJSONPb), // 兜底方案:客户端没明确指定 Content-Type 时用这个 - runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{ - MarshalOptions: protojson.MarshalOptions{ - EmitUnpopulated: true, - UseProtoNames: true, - }, - UnmarshalOptions: protojson.UnmarshalOptions{ - DiscardUnknown: false, - }, - }), + runtime.WithMarshalerOption(runtime.MIMEWildcard, defaultJSONPb), }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api/grpc_gateway/mux.go` around lines 26 - 54, The three runtime.WithMarshalerOption calls in mux.go repeat identical runtime.JSONPb settings; extract the common runtime.JSONPb (or its MarshalOptions/UnmarshalOptions) into a single shared variable (e.g., baseJSONPb or jsonPBOptions) and reuse it in the calls to runtime.WithMarshalerOption for "application/json", "application/jsonpb", and runtime.MIMEWildcard; update the existing calls that currently construct a new &runtime.JSONPb with protojson.MarshalOptions and protojson.UnmarshalOptions to reference the shared variable instead and ensure the variable is defined near the top of the mux setup (so functions creating the mux can reuse it)..gitignore (1)
3-3: 建议确认忽略test_marshaler.go的必要性。忽略根目录下的
.go文件不太常见。如果这是用于本地调试的临时文件,建议考虑:
- 将其移动到独立的测试目录或使用
_test.go后缀- 或者在 PR 中说明该文件的用途
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gitignore at line 3, 当前 .gitignore 把根目录下的 test_marshaler.go 忽略了,请确认是否真的需要忽略该文件:如果这是临时/本地调试文件,建议将 test_marshaler.go 移到一个独立目录或重命名为以 _test.go 结尾(便于 go 工具识别);如果该文件必须保留在根目录且不应被忽略,则从 .gitignore 中移除 test_marshaler.go;若保留忽略,请在 PR 描述中说明 test_marshaler.go 的用途以便审阅者理解。
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@api/grpc_gateway/mux.go`:
- Around line 31-33: The protojson UnmarshalOptions currently sets
DiscardUnknown: false which causes JSON unmarshal to fail on unknown fields;
update the protojson.UnmarshalOptions used to configure the HTTP->gRPC JSON
parsing (the UnmarshalOptions block) to set DiscardUnknown: true if you want
forward-compatibility so new/unknown fields in requests are ignored, or
explicitly document/keep false if strict rejection of unknown fields is
intended; change the DiscardUnknown value on the UnmarshalOptions struct
accordingly.
---
Nitpick comments:
In @.gitignore:
- Line 3: 当前 .gitignore 把根目录下的 test_marshaler.go
忽略了,请确认是否真的需要忽略该文件:如果这是临时/本地调试文件,建议将 test_marshaler.go 移到一个独立目录或重命名为以 _test.go
结尾(便于 go 工具识别);如果该文件必须保留在根目录且不应被忽略,则从 .gitignore 中移除 test_marshaler.go;若保留忽略,请在
PR 描述中说明 test_marshaler.go 的用途以便审阅者理解。
In `@api/grpc_gateway/mux.go`:
- Around line 26-54: The three runtime.WithMarshalerOption calls in mux.go
repeat identical runtime.JSONPb settings; extract the common runtime.JSONPb (or
its MarshalOptions/UnmarshalOptions) into a single shared variable (e.g.,
baseJSONPb or jsonPBOptions) and reuse it in the calls to
runtime.WithMarshalerOption for "application/json", "application/jsonpb", and
runtime.MIMEWildcard; update the existing calls that currently construct a new
&runtime.JSONPb with protojson.MarshalOptions and protojson.UnmarshalOptions to
reference the shared variable instead and ensure the variable is defined near
the top of the mux setup (so functions creating the mux can reuse it).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8c77f9d2-096e-43eb-b45c-f1d6cccaa95e
📒 Files selected for processing (2)
.gitignoreapi/grpc_gateway/mux.go
| UnmarshalOptions: protojson.UnmarshalOptions{ | ||
| DiscardUnknown: false, | ||
| }, |
There was a problem hiding this comment.
DiscardUnknown: false 会拒绝包含未知字段的请求。
当设置为 false 时,如果请求 JSON 中包含 proto 定义中不存在的字段,反序列化将失败。这比默认行为更严格。
请确认这是预期行为。如果希望保持向前兼容性(允许客户端发送新字段而旧服务端忽略),建议设置为 true。
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@api/grpc_gateway/mux.go` around lines 31 - 33, The protojson UnmarshalOptions
currently sets DiscardUnknown: false which causes JSON unmarshal to fail on
unknown fields; update the protojson.UnmarshalOptions used to configure the
HTTP->gRPC JSON parsing (the UnmarshalOptions block) to set DiscardUnknown: true
if you want forward-compatibility so new/unknown fields in requests are ignored,
or explicitly document/keep false if strict rejection of unknown fields is
intended; change the DiscardUnknown value on the UnmarshalOptions struct
accordingly.
背景
线上偶发报错:Failed to parse Content-Type: mime: no media type。
原因是网关只配置了 application/jsonpb,当客户端使用 application/json 或未明确传递内容协商头时,可能匹配失败。
本次修改
在网关 ServeMux 中新增 application/json 的 marshaler 配置
保留 application/jsonpb 的 marshaler 配置
新增 MIMEWildcard 兜底 marshaler,兼容未显式声明内容类型的请求
预期效果
支持 application/json 请求
支持 application/jsonpb 请求
在未显式传递 Accept/Content-Type 时仍可正常处理
避免再次出现 Content-Type 解析失败问题
Summary by CodeRabbit
发布说明