七牛云官方 Go SDK,模块路径 github.com/qiniu/go-sdk/v7,Go 1.22+,MIT 许可。
本文档面向 SDK 维护者和贡献者,帮助理解项目结构、架构模式和开发流程。
SDK 的 API 使用说明请参考各包的 doc.go 文件和 examples/ 目录。
| 包 | 职责 |
|---|---|
auth |
认证凭证(AK/SK)、HMAC-SHA1 签名、上传凭证、回调验证 |
storage |
对象存储 v1:表单上传、分片上传、Bucket/对象管理、数据处理(pfop) |
storagev2 |
对象存储 v2:类型化 API、自动区域检测、连接池、重试、Provider/Interface 模式 |
cdn |
CDN 加速:刷新、预取、流量/带宽查询、时间戳防盗链 |
pili |
直播云:流管理、域名管理、推拉流地址生成 |
rtc |
实时音视频:应用管理、房间 Token、用户管理 |
sms |
短信:发送短信、签名/模板管理 |
linking |
IoT 设备联网:设备管理、密钥、录像片段 |
qvs |
视频监控(QVS):GB/T 28181 设备接入、空间/设备/流管理 |
iam |
身份与访问管理:用户、组、策略 CRUD(生成代码) |
media |
多媒体处理:Pfop 触发/Prefop 查询(生成代码) |
audit |
审计日志:日志查询(生成代码) |
sandbox |
沙箱环境:创建/管理沙箱、文件操作、命令执行、PTY 终端 |
client |
底层 HTTP 客户端:请求签名、JSON/表单序列化、错误解析 |
conf |
全局配置:SDK 版本号(conf.Version)、User-Agent 设置 |
reqid |
请求 ID:通过 Context 传递 X-Reqid |
| 包 | 职责 |
|---|---|
internal/api-generator |
代码生成器:读取 YAML API 规范生成类型化 Go 代码 |
internal/clientv2 |
HTTP 客户端 v2:拦截器链模式、认证注入、重试、防劫持 |
internal/cache |
通用缓存 |
internal/hostprovider |
主机地址提供者 |
internal/freezer |
主机冻结/降级 |
internal/context |
Context 兼容层 |
internal/env |
环境变量读取 |
internal/log |
内部日志 |
internal/uplog |
上传日志 |
internal/io |
IO 工具 |
internal/dialer |
网络拨号 |
internal/configfile |
配置文件读取 |
| 包 | 职责 |
|---|---|
storagev2/apis |
低级 API 客户端,所有方法由代码生成器生成 |
storagev2/apistest |
API mock/测试辅助 |
storagev2/credentials |
凭证管理(Provider 接口) |
storagev2/http_client |
HTTP 客户端选项、拦截器集成 |
storagev2/region |
区域信息(RegionsProvider 接口) |
storagev2/uploader |
上传管理器(自动选择上传方式) |
storagev2/downloader |
下载管理器 |
storagev2/objects |
对象管理(流式 API) |
storagev2/uptoken |
上传凭证(PutPolicy → Signer) |
storagev2/backoff |
重试退避策略 |
storagev2/chooser |
主机选择器 |
storagev2/resolver |
域名解析器 |
storagev2/retrier |
重试器 |
storagev2/defaults |
默认配置值 |
storagev2/errors |
类型化错误 |
storagev2/uplog |
上传日志 |
storagev2/internal |
storagev2 内部实现 |
| 目录 | 说明 |
|---|---|
api-specs/ |
API 规范(git submodule),包含 storage、iam、media、audit、sandbox 的 YAML/OpenAPI 定义 |
examples/ |
各功能的使用示例,每个示例是独立子目录(独立 main 包) |
v1 的对象存储使用 Manager 模式,每个功能域对应一个 Manager 结构体:
storage.BucketManager— Bucket 和对象管理storage.FormUploader/storage.ResumeUploader— 上传storage.OperationManager— 数据处理
构造方式统一为 New*(mac, &cfg) 或 New*(&cfg),通过 auth.Credentials 传递认证信息。
v2 通过接口抽象实现可插拔:
credentials.CredentialsProvider— 凭证提供者region.RegionsProvider— 区域信息提供者chooser.Chooser— 主机选择策略resolver.Resolver— 域名解析retrier.Retrier— 重试策略backoff.Backoff— 退避策略
所有组件通过 http_client.Options 注入,支持自定义替换。
HTTP 请求通过拦截器链处理,拦截器按优先级排序(数字越小优先级越高):
RetryHosts(200) → RetrySimple(300) → Uplog(310) → BufferResponse(320)
→ SetHeader(400) → Normal(500) → Auth(600) → AntiHijacking(700) → Debug(800)
核心接口:
type Interceptor interface {
Priority() InterceptorPriority
Intercept(req *http.Request, handler Handler) (*http.Response, error)
}storage v1 通过函数参数传递 auth.Credentials,storagev2 通过 http_client.Options 结构体传递。reqid 包提供 Context 传递请求 ID 的机制(X-Reqid 头)。
storage(v1)和 storagev2(v2)并行维护:
- v1:稳定的对外 API,Manager 模式,手写代码
- v2:新一代 API,Provider/Interface 模式,代码生成 + 手写
- 两者共享
auth、client、conf、reqid等基础包 - 新功能优先在 v2 实现,v1 仅做维护性修改
internal/api-generator 读取 api-specs/ 中的 YAML 规范,生成类型化 Go 代码:
api-specs/<service>/*.yml → internal/api-generator → <service>/apis/*.go
涉及的包及 //go:generate 指令:
storagev2/→storagev2/apis/(struct: Storage)iam/→iam/apis/(struct: IAM)media/→media/apis/(struct: Media)audit/→audit/apis/(struct: Audit)
运行命令:
make generate # 运行所有 go generate 并格式化代码sandbox 使用不同的生成工具链:
- 控制面 API:
oapi-codegen(OpenAPI → Go)→sandbox/internal/apis/ - envd HTTP API:
oapi-codegen→sandbox/internal/envdapi/ - envd ConnectRPC:
buf+protoc-gen-go+protoc-gen-connect-go→sandbox/internal/envdapi/
运行命令:
make generate-sandbox # 需要安装 buf、protoc-gen-go、protoc-gen-connect-go所有生成的代码文件首行包含如下标记之一:
// THIS FILE IS GENERATED BY api-generator, DO NOT EDIT DIRECTLY!// Code generated by protoc-gen-go. DO NOT EDIT.// Code generated by protoc-gen-connect-go. DO NOT EDIT.// Code generated by github.com/oapi-codegen/oapi-codegen/v2 ... DO NOT EDIT.
绝对不要手动修改这些文件,如需修改请更新对应的 API 规范后重新生成。
- 使用
gofmt -s格式化代码(CI 会检查) make generate会自动运行gofmt -w .和gofumpt -w .
- 使用
staticcheck(CI 会检查) - 运行:
make staticcheck
- 注释默认使用中文
- 导出的 API、函数、类型、常量、变量必须添加注释
- 注释以被注释的标识符名称开头(符合 Go 官方 godoc 规范)
- 包级别注释写在
doc.go的package声明之前
- 构造函数使用
New*()或New*Ex()命名 - 错误类型:根包使用
client.ErrorInfo(Code + Err + Reqid),storagev2 使用storagev2/errors包
- 错误使用 Go 标准的
fmt.Errorf("context: %w", err)包装 - 使用
errors.Is()/errors.As()判断错误类型
测试文件必须添加 build tag:
//go:build unit
package xxx_testunit— 单元测试,不依赖外部服务integration— 集成测试,需要七牛账号和网络
| 命令 | 说明 |
|---|---|
make unittest |
运行单元测试(提交前必须通过) |
make integrationtest |
运行集成测试(需要环境变量配置) |
make test |
运行所有测试 |
所有测试命令排除 examples/ 和 sms/ 目录。
- 使用
testify/assert进行断言 - 推荐使用表驱动测试
- mock 测试可参考
storagev2/apistest包
CI 在 push 和 pull_request 时触发(.github/workflows/ci-test.yml):
Go 1.22 + stable 两个版本矩阵:
- gofmt 检查(仅 stable):
gofmt -s -l .检查未格式化文件 - staticcheck(仅 stable):
make staticcheck - 编译 examples(仅 stable):
go build ./examples/... - 单元测试(两个版本):
make unittest
Linux 通过后依次运行,仅执行 make unittest(stable 版本)。
发布 tag 时(.github/workflows/version-check.yml),检查以下三处版本号一致:
CHANGELOG.md包含## <version>README.md包含require github.com/qiniu/go-sdk/v7 v<version>conf/conf.go包含const Version = "<version>"
# 初始化 api-specs submodule
git submodule update --init --recursive
# 验证当前状态
make unittest
make staticcheck- 确保分支基于最新 master:
git fetch upstream && git rebase upstream/master - 修改代码前先运行
make unittest确认当前状态 - 修改 API 规范后运行
make generate或make generate-sandbox - 提交前运行
make unittest和make staticcheck确保通过 - 代码格式化:
gofmt -s -w .
- 更新
api-specs/中对应的 YAML 规范(如需) - 运行
make generate(或make generate-sandbox) - 检查生成结果,确认无误后提交规范和生成代码
实现新功能或修复 bug 时,应同时提供单元测试和集成测试。对于涉及幂等、重试等逻辑的接口,单元测试用 mock 覆盖边界条件,集成测试用真实凭证验证端到端行为。
# 单测(提交前必须通过)
make unittest
# 特定包的单测
go test -tags=unit -count=1 -v ./sandbox/
# 集成测试(需要 .env 文件)
set -a && source sandbox/.env && set +a && go test -tags=integration -count=1 -v ./sandbox/sandbox/.env 用于集成测试和示例程序的环境变量配置:
QINIU_API_KEY= # 七牛 API Key(必填)
QINIU_SANDBOX_API_URL= # API 端点(可选,默认 https://cn-yangzhou-1-sandbox.qiniuapi.com)
SANDBOX_RETRY_MAX= # 可重试 API 的最大重试次数(可选,默认 5,设为 0 禁用重试)
使用方式:
cd sandbox/
set -a && source .env && set +a
# 后续 go test / go run 命令可直接读取环境变量# 需要先 source sandbox/.env
go run ./examples/sandbox_idempotency_retry/- 不要手动修改生成代码 — 带
DO NOT EDIT DIRECTLY标记的文件由代码生成器维护 - 不要删除 sms 测试排除 — Makefile 中
egrep -v 'examples|sms'是有意为之 - examples 是独立子目录 — 每个示例是独立的
main包,编译方式为go build ./examples/... - 版本号三处同步 — 发布时确保
conf/conf.go、CHANGELOG.md、README.md版本一致 - api-specs 是 git submodule — 更新规范需要在 submodule 中操作
- 保持双版本兼容 — storage v1 和 storagev2 v2 并行维护,不要在 v1 中引入 v2 的依赖