Files
go-omni/examples/userService/README.md
k2safe 7670b222ac feat: release configurable API response contracts
Define reusable response bodies in .api with typed code mappings, per-route overrides and matching OpenAPI schemas. Add application and callback encoders, early response policy selection, and isolated remote-consumer release verification.

Release v0.8.0-preview after full race, vet, build and local MySQL workflow acceptance.
2026-09-23 20:42:38 +08:00

4.4 KiB
Raw Permalink Blame History

API 驱动的用户管理示例

这个独立 Go module 从 api/user.api 生成,随后在开发者拥有的文件中实现业务。 使用 MySQL 持久化、事务审计、环境变量 Token 鉴权、文件日志和 local 存储;业务层只接收标准 context 和基础模块接口。

启动

先准备空的业务数据库,再设置环境变量(替换占位值,密钥不写进配置或 Git):

export GO_OMNI_DB_DSN='user:password@tcp(127.0.0.1:3306)/user_service?parseTime=true'
export USER_SERVICE_API_TOKEN='<至少32字节的随机值>'
export GO_OMNI_STORAGE_SIGNING_KEY='<另一个至少32字节的随机值>'
export GO_OMNI_STORAGE_PUBLIC_URL='http://127.0.0.1:8080/storage/object'
go mod tidy
# 在本目录运行与框架版本一致的 CLI;迁移必须显式执行。
go-omni migrate --dir migrations --apply
go run ./cmd/server

源码示例的 go.mod 使用 replace ... => ../..。生成代码使用 v0.8.0-preview 响应策略入口。 复制到独立仓库时删除 replace,保留同版本固定依赖,再执行 go mod tidy;CLI 也固定到同一版本。 远程版本验证脚本会检查没有本地替换。 GO_OMNI_TRANSPORT=native 可切换为 native,业务代码无需调整。

配置是默认值 → etc/config.yaml → 环境变量。日志默认写入 var/log/server.log 并轮转, GO_OMNI_LOG_OUTPUT=stderr 可以切换为标准错误输出。MySQL 默认最多 10 条连接。 应用检查 users 和 user_audit 表,缺失时拒绝启动,不自动改表。

接口

除健康检查、OpenAPI 和持有效签名的对象下载外,业务接口需要 Authorization: Bearer <Token>。 这个 Token 代表示例的管理员;可选设置不同的 USER_SERVICE_READ_TOKEN,允许 GET/HEAD,写请求返回 403。可通过同一个命名中间件槽位替换为 JWT/OIDC 和业务授权策略。 框架不会推断租户模型或自动给接口放行。

接口 行为
POST /api/v1/users 创建,返回 201;邮箱规范化并唯一
GET /api/v1/users/:id 查询,缺失返回 404
GET /api/v1/users?page=1&pageSize=20 分页,pageSize 最大 100,空结果返回 []
PUT /api/v1/users/:id 完整更新;邮箱冲突返回 409
DELETE /api/v1/users/:id 删除,返回 204
POST /api/v1/users/:id/export 私有文本导出,返回 5 分钟下载链接
GET /health/ready 数据库不可用时返回 503,恢复后重新就绪
GET /openapi.json 与 docs/openapi.json 一致

参数不合法返回 400,认证失败 401,只读身份写入 403,邮箱重复 409,内部故障只返回通用 500。 OpenAPI 的数据类型、鉴权和业务错误均来自契约;401/403/404/409 带具体命名示例。业务使用生成的 apierrors.UserNotFound()、apierrors.EmailTaken() 等函数。

创建、更新、删除都会在同一个 MySQL 事务写入 user_audit;审计写入失败时业务变更一起回滚。 事务提交后才写成功业务日志,requestId 同时出现在 HTTP 响应、业务日志和审计记录。 数据库异常日志不记录 SQL、DSN 或用户输入。

文件导出演示 deps.Uploads 和 deps.Downloads。对象使用随机 key,签名 URL 不进入日志。 签名过期只限制下载,不删除文件;实际项目应给 exports/ 配置保留期限或清理任务。 只签发下载链接,不对外开放任意对象上传或签名接口。

开发与验证

go-omni api inspect
go-omni api generate --dry-run
go-omni api generate
go-omni api generate --check
go test ./...

Gen.go 和 docs/openapi.json 由生成器维护;Service、Repository、迁移、鉴权、配置和 main 保留。 修改 .api 的类型/方法签名后,需要同步修改自己的业务实现并运行测试。

在框架仓库运行:

python3 scripts/verifyAPIWorkflow.py --report performance/responsePoliciesWorkflowLocal.json
# 使用本版远程 CLI 和模块验收,无本地替换。
python3 scripts/verifyAPIWorkflow.py --version v0.8.0-preview \
  --report performance/responsePoliciesWorkflowRemote.json

验收创建只绑定 localhost 的临时 MySQL 容器(1 CPU / 768 MiB),使用随机密钥,结束时删除。 覆盖 nethttp/native 的 CRUD、校验、鉴权、事务错误/异常/取消回滚、数据库停机恢复、 重启持久化、签名文件下载、文件日志与优雅退出。不会连接业务服务器。