grpc-gateway需三步协同:protoc分两轮生成代码(先.go/.grpc.pb.go,再.pb.gw.go)、proto中google.api.http注解须严格匹配字段与路径、registerxxxhandlerfromendpoint必须在http.listenandserve前显式调用,任一缺失均导致404或400。

gRPC-Gateway 不是“一键开关”,它需要三步协同:protoc 分两轮生成代码、proto 注解写对、handler 显式注册——漏掉任一环,HTTP 接口就 404 或 400。
protoc 必须分两次执行,不能合并
很多人试图用一条 protoc 命令同时生成 .pb.go、_grpc.pb.go 和 .pb.gw.go,结果要么报错 google/api/annotations.proto: File not found,要么 .pb.gw.go 是空文件。
-
--go_out和--go-grpc_out负责解析 proto 结构,生成 message 和 service stub;它们必须先跑,确保.pb.go和_grpc.pb.go存在 -
--grpc-gateway_out只读取已有定义,生成反向代理逻辑;它不参与 protobuf 解析,所以必须后跑 - third_party/googleapis 路径必须显式传入:
-I $GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v2.15.2/third_party/googleapis/,否则注解无法识别
google.api.http 注解写错一个字符,HTTP 就 404
这个注解不是装饰,是路由和参数绑定的唯一依据。大小写、引号、字段名、路径占位符,全都要和 proto message 定义严格一致。
通过Gate-Info和Gate-News MCP进行宏观驱动的加密货币分析,用于CPI、NFP、美联储、利率、工资等宏观因素与加密货币、日历或指标的关联。
-
post: "/v1/users"要求body: "*"—— 漏写返回 400,不是 404 -
get: "/v1/users/{id}"要求 message 中存在string id = 1;;若字段是user_id却写成{id},gateway 直接跳过路由,404 - query 参数如
get: "/v1/users?status={status}",status必须是一级字段,UserFilter.status这类嵌套结构不支持自动展开 - 避免换行缩进写法:
option (google.api.http) = { post: "/v1/foo" };在某些旧版 protoc 下会被静默忽略
RegisterXXXHandlerFromEndpoint 必须在 ListenAndServe 前调用
生成的 .pb.gw.go 文件里提供类似 RegisterSumHandlerFromEndpoint 的函数,它把反向代理 handler 挂载到 runtime.ServeMux 上。这个动作不可省略,也不可延迟。
- 不调用 → mux 为空 → 所有请求 404
- 塞进 Gin/Echo 路由树(比如
r.POST("/xxx", mux.ServeHTTP))→ 框架丢失 method/path 匹配 → 全部 fallback 到 404 - 必须用
http.ListenAndServe(":8080", mux)或http.Server{Handler: mux}直接启动 -
ctx参数不能是已 cancel 的 context(例如从context.WithTimeout创建后超时了),否则注册失败且无任何提示
endpoint 必须指向正在运行的 gRPC server
RegisterXXXHandlerFromEndpoint 内部会用 grpc.Dial 连接后端。地址不可达、未监听、DNS 解析失败或防火墙拦截,都会导致 503 Service Unavailable。
- 本地开发推荐用
127.0.0.1:9090,避免localhost在 Docker 或 IPv6 环境下的解析歧义 - Docker 部署时需改成容器名(
"grpc-server:9090")或宿主机别名("host.docker.internal:9090") - gRPC server 必须先启动、监听成功,再初始化 gateway mux;顺序颠倒会导致 dial timeout
- 想共用 8080 端口同时响应 REST 和 gRPC?不能起两个
ListenAndServe,也不能让 gRPC server 直接Serve(lis)—— 正确做法是用h2c.NewHandler包裹 gRPC server 作为 fallback handler
最常被忽略的是注解与 message 字段的严格对应关系,以及注册 handler 的时机——这两处出错,不会报编译错误,但请求永远得不到响应。










