508 字
3 分钟
protoc-gen-gin:让 Proto 定义同时支持 gRPC 和 HTTP 的代码生成器
项目背景
在开发微服务时,我们经常需要同时提供 gRPC 和 HTTP RESTful 两种接口。传统做法是分别编写两套代码,这不仅增加了开发工作量,还容易造成接口不一致。受 B 站开源的 Kratos 框架启发,我开发了 protoc-gen-gin
,一个专门为 Gin 框架生成 HTTP 处理代码的 protoc 插件。
核心特性
1. 一份定义,双协议支持
只需在 proto 文件中添加 HTTP 注解,即可自动生成对应的 Gin HTTP 处理器:
service UserService { rpc GetUser(GetUserRequest) returns (GetUserResponse) { option (google.api.http) = { get: "/api/v1/users/{user_id}" }; }}
2. 智能参数绑定
根据 HTTP 方法自动选择参数绑定方式:
- GET/DELETE 请求:Query 参数
- POST/PUT/PATCH 请求:JSON Body
- 路径参数:自动从 URL 提取
3. 灵活的错误处理
内置 gRPC 错误码到 HTTP 状态码的映射,同时支持自定义错误处理器:
// 使用默认错误处理pb.RegisterUserServiceHTTPServer(srv, r)
// 或自定义错误处理pb.RegisterUserServiceHTTPServer(srv, r, pb.WithErrorHandler(customHandler))
4. 单体与微服务双模式
同一套代码可以在单体应用和微服务架构间无缝切换:
- 单体模式:直接访问数据库,返回业务错误
- 分布式模式:作为 API Gateway,转发请求到后端 gRPC 服务
技术实现
项目采用 protogen
包实现代码生成,核心流程:
- 解析 proto 文件中的
google.api.http
注解 - 转换路径参数格式(
{param}
→:param
) - 根据 HTTP 方法生成对应的参数绑定代码
- 使用 Go template 生成最终代码
使用方式
安装插件:
go install github.com/JarrettGuo/protogin/cmd/protoc-gen-gin@latest
生成代码:
protoc --gin_out=. --gin_opt=paths=source_relative api.proto
项目价值
- 提高开发效率:减少重复代码编写
- 保证接口一致性:从同一 proto 定义生成
- 架构灵活性:支持从单体到微服务的演进
- 降低维护成本:修改 proto 即可更新所有接口
未来规划
- 支持流式 RPC
- 生成 OpenAPI 文档
- 添加请求验证
- 支持中间件链式调用
protoc-gen-gin:让 Proto 定义同时支持 gRPC 和 HTTP 的代码生成器
https://fuwari.vercel.app/posts/protoc-gen-gin/