508 字
3 分钟
protoc-gen-gin:让 Proto 定义同时支持 gRPC 和 HTTP 的代码生成器

项目背景#

在开发微服务时,我们经常需要同时提供 gRPC 和 HTTP RESTful 两种接口。传统做法是分别编写两套代码,这不仅增加了开发工作量,还容易造成接口不一致。受 B 站开源的 Kratos 框架启发,我开发了 protoc-gen-gin,一个专门为 Gin 框架生成 HTTP 处理代码的 protoc 插件。

项目地址:https://github.com/JarrettGuo/protogin

核心特性#

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 包实现代码生成,核心流程:

  1. 解析 proto 文件中的 google.api.http 注解
  2. 转换路径参数格式({param}:param
  3. 根据 HTTP 方法生成对应的参数绑定代码
  4. 使用 Go template 生成最终代码

使用方式#

安装插件:

Terminal window
go install github.com/JarrettGuo/protogin/cmd/protoc-gen-gin@latest

生成代码:

Terminal window
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/
作者
Jarrett
发布于
2025-09-02
许可协议
CC BY-NC-SA 4.0