本指南说明如何在 proto 文件中编写注释,以便通过 go-kratos 工具链自动生成 OpenAPI 3.0 规范文档。
AnyChat 使用 go-kratos 框架的原生代码生成能力,通过 protoc-gen-openapi 插件直接从 .proto 文件生成 OpenAPI 3.0 规范。API 文档与接口定义保持单一数据源,proto 文件即文档。
核心原则: proto 文件中的注释和 google/api/http 注解驱动 OpenAPI 文档生成,无需在 Go handler 中额外编写文档注释。
.proto 文件
│ (protoc + protoc-gen-openapi)
▼
docs/api/swagger/openapi.json (OpenAPI 3.0 规范)
│ (Docsify + docsify-openapi 插件)
▼
交互式 API 文档页面
# 生成 protobuf 代码 + OpenAPI 文档(一步完成)
mage proto
# 仅生成 OpenAPI 文档
mage docs:generate
# 本地预览文档
mage docs:serve在 service 关键字前添加服务描述:
// UserService 用户服务,提供用户注册、登录、Token 管理等接口
service UserService {}在每个 rpc 方法前添加描述:
// Register 用户注册
rpc Register(RegisterRequest) returns (RegisterResponse);
// Login 用户登录
rpc Login(LoginRequest) returns (LoginResponse);注释内容会映射到 OpenAPI 的
summary字段。注释的第一行作为摘要,后续行作为详细描述。
在 message 关键字前添加描述:
// LoginRequest 登录请求
message LoginRequest {
// 账号(手机号或邮箱)
string account = 1;
// 密码
string password = 2;
// 设备类型
DeviceType device_type = 3;
// 设备 ID
string device_id = 4;
}字段注释会映射到 OpenAPI schema 的 description 属性。
使用 google.api.http 注解将 gRPC 方法映射为 HTTP 端点。
import "google/api/annotations.proto";rpc Login(LoginRequest) returns (LoginResponse) {
option (google.api.http) = {
post: "/user/login"
body: "*"
};
}rpc GetProfile(GetProfileRequest) returns (GetProfileResponse) {
option (google.api.http) = {
get: "/users/{user_id}"
};
}// PUT 请求(更新资源)
rpc UpdateProfile(UpdateProfileRequest) returns (UpdateProfileResponse) {
option (google.api.http) = {
put: "/users/me"
body: "*"
};
}
// DELETE 请求(删除资源)
rpc DeleteFriend(DeleteFriendRequest) returns (DeleteFriendResponse) {
option (google.api.http) = {
delete: "/friends/{friend_id}"
};
}| HTTP 方法 | 语义 | 示例 |
|---|---|---|
get |
获取资源 | get: "/users/{user_id}" |
post |
创建资源 | post: "/user/login" |
put |
更新资源 | put: "/users/me" |
patch |
部分更新 | patch: "/users/me" |
delete |
删除资源 | delete: "/friends/{id}" |
OpenAPI 中的 Bearer Token 认证信息在 proto 文件顶部通过全局注释配置:
syntax = "proto3";
package anychat.auth;
// AnyChat Gateway API 文档
//
// description: AnyChat 即时通讯系统网关 API 服务,提供用户认证、用户管理等 HTTP 接口。
// 所有需要认证的接口必须在 Header 中包含 Authorization: Bearer <token>。
//
// title: AnyChat Gateway API
// version: 1.0
// contact.name: AnyChat API Support
// contact.url: https://github.com/yzhgit/anychat-server
// contact.email: support@anychat.example.com
// license.name: MIT
// license.url: https://opensource.org/licenses/MIT需要认证的接口会在 OpenAPI 中自动标记 security: BearerAuth。
枚举值和枚举项的注释会被正确映射:
// 设备类型
enum DeviceType {
DEVICE_TYPE_UNSPECIFIED = 0;
DEVICE_TYPE_IOS = 1; // iOS
DEVICE_TYPE_ANDROID = 2; // Android
DEVICE_TYPE_WEB = 3; // Web
DEVICE_TYPE_PC = 4; // PC 客户端
DEVICE_TYPE_H5 = 5; // H5
}以下是一个完整的 proto 文件示例:
syntax = "proto3";
package anychat.auth;
import "google/api/annotations.proto";
// UserService 用户服务
service UserService {
// Register 用户注册
rpc Register(RegisterRequest) returns (RegisterResponse) {
option (google.api.http) = {
post: "/user/register"
body: "*"
};
}
// Login 用户登录
rpc Login(LoginRequest) returns (LoginResponse) {
option (google.api.http) = {
post: "/user/login"
body: "*"
};
}
// RefreshToken 刷新 Token
rpc RefreshToken(RefreshTokenRequest) returns (RefreshTokenResponse) {
option (google.api.http) = {
post: "/user/refresh"
body: "*"
};
}
}
// RegisterRequest 注册请求
message RegisterRequest {
// 手机号
string phone_number = 1;
// 密码
string password = 2;
// 验证码
string verify_code = 3;
// 昵称
string nickname = 4;
// 设备类型
DeviceType device_type = 5;
// 设备 ID
string device_id = 6;
}
// LoginRequest 登录请求
message LoginRequest {
// 账号(手机号或邮箱)
string account = 1;
// 密码
string password = 2;
// 设备类型
DeviceType device_type = 3;
// 设备 ID
string device_id = 4;
}
// LoginResponse 登录响应
message LoginResponse {
// 用户 ID
string user_id = 1;
// 访问令牌
string access_token = 2;
// 刷新令牌
string refresh_token = 3;
// 过期时间(秒)
int64 expires_in = 4;
}
// 设备类型
enum DeviceType {
DEVICE_TYPE_UNSPECIFIED = 0;
DEVICE_TYPE_IOS = 1;
DEVICE_TYPE_ANDROID = 2;
DEVICE_TYPE_WEB = 3;
DEVICE_TYPE_PC = 4;
DEVICE_TYPE_H5 = 5;
}# 完整生成(protobuf 代码 + OpenAPI 文档)
mage proto
# 仅生成 OpenAPI 文档
mage docs:generate
# 验证文档完整性
mage docs:validate
# 本地预览(http://localhost:3000)
mage docs:serve文档在以下情况自动生成:
- 推送到
main分支时自动部署到 GitHub Pages - Pull Request 时自动验证文档生成结果
- 服务/方法注释用一句话概括功能
- 字段注释说明字段用途和约束
- 避免冗余信息
修改接口时同步更新注释:
# 修改 proto 文件后
vim api/user/v1/user.proto
# 重新生成代码和文档
mage protoHTTP 路径遵循 RESTful 规范:
// 好的路径设计
get: "/users/{user_id}" // 获取用户
post: "/friends" // 添加好友
delete: "/friends/{friend_id}" // 删除好友
// 避免
post: "/getUserInfo" // 动词风格
get: "/do-search-users" // 不清晰enum DeviceType {
DEVICE_TYPE_UNSPECIFIED = 0; // 明确的默认值
DEVICE_TYPE_IOS = 1; // 清晰命名
}每次修改 .proto 文件后运行:
mage proto运行 mage proto 重新生成 OpenAPI 文档。
确保:
- 该 RPC 方法添加了
option (google.api.http)注解 - 运行了
mage proto生成文档
# 查看生成的 openapi.json
cat docs/api/swagger/openapi.json | jq '.paths'
# 查看特定路径
cat docs/api/swagger/openapi.json | jq '.paths["/user/login"]'是的,OpenAPI 3.0 支持 UTF-8 编码,中文注释会被正确保留。