Kratos中HTTP接口暴露需严格遵循protobuf的google.api.http注解规范:路径须以/开头、动词后跟英文冒号、变量名须与message字段完全一致且禁用下划线;路径前缀由注解和Group()共同决定,重复会导致404;多动词需分别声明。

要在Kratos中让HTTP接口正确暴露并响应请求,必须严格遵循protobuf中google.api.http注解的语法规范和路径生成逻辑,否则即使服务启动成功,curl访问也会返回404。
注解语法必须写对
在.proto文件的rpc方法定义后,添加option (google.api.http) = { ... };时,花括号内必须用英文冒号:分隔动词与路径,且路径必须以/开头。
正确写法:get: "/v1/device/list";错误写法:get "/v1/device/list"(缺冒号)、get: "v1/device/list"(缺首斜杠)。
路径中若含变量,必须用大括号包裹,且变量名需与请求消息字段名完全一致,大小写敏感。例如:get: "/v1/device/{id}" → 对应HelloRequest中必须有string id = 1;字段。
【id字段类型必须是string或int32/int64,不能是uint32/uint64——Kratos HTTP路由解析器不支持无符号整型路径变量】
路径前缀不是固定死的
Kratos不会自动给所有路由加/v1前缀,前缀完全由你写的注解内容决定。
如果你写get: "/device/list",那真实路径就是http://localhost:8000/device/list,不是/v1/device/list。
但官方模板默认在make命令生成的server注册代码里会绑定到/v1组,所以实际生效路径取决于两处:一是注解里的路径字面量,二是http.Server.Group()调用时传入的prefix参数。
常见陷阱:proto里写了get: "/v1/device/list",又在http.go里调用srv.Group("/v1", ...) → 实际路径变成/v1/v1/device/list,必然404。
多方法共用同一路径需显式区分
同一个URL路径支持不同HTTP动词,必须分别声明:
方法一:get: "/v1/device/{id}" → 处理GET请求
方法二:put: "/v1/device/{id}" → 处理PUT请求
方法三:delete: "/v1/device/{id}" → 处理DELETE请求
这三行必须各自独立写在对应rpc方法后面,不能合并成一行,也不能漏掉任意一个动词声明。
注意:Kratos生成的HTTP handler会按动词精确匹配,get:声明的路径不会响应PUT请求,反之亦然。
路径变量名带下划线会失效
第一步:检查你的proto中路径变量是否含下划线,例如get: "/v1/user/{user_id}"
第二步:确认HelloRequest消息中是否有string user_id = 1;字段
第三步:运行make api重新生成代码,打开api/v1/device_http.pb.go搜索user_id
如果生成的handler函数里仍出现"/v1/user/{user_id}"字面量而非被替换成实际值,说明变量替换失败——这是Kratos当前版本已知限制:【路径变量名禁止含下划线,必须改用驼峰如userId或单单词id】
这一步不做修正,客户端调用PUT/DELETE时永远拿不到真实ID,只会发过去{user_id}这个字符串。



















