feat: release managed service generation and contract diagnostics
This commit is contained in:
66
README.md
66
README.md
@@ -1,8 +1,10 @@
|
||||
# GoOmni
|
||||
|
||||
GoOmni 是面向多个业务项目复用的 Go 后端框架:用 `.api` 定义接口、请求和返回类型,生成项目目录、HTTP 接入代码及 OpenAPI,业务代码负责 Service 和 Repository。也可以在已有项目中直接使用 `omni.New()`,或单独引入日志、存储等模块。
|
||||
GoOmni 是面向多个业务项目复用的 Go 后端框架:用 `.api` 定义接口、请求和返回类型,生成项目目录、HTTP 接入代码及 OpenAPI,业务代码负责 Logic 和 Repository。也可以在已有项目中直接使用 `omni.New()`,或单独引入日志、存储等模块。
|
||||
|
||||
**从这份 README 开始即可接入。** 当前版本为 **`v0.11.1-preview`**,Go **1.22+**;CLI 和项目依赖使用同一固定版本。框架不依赖 Gin,默认使用标准库网络层,提供可切换的 native HTTP/1.1 和实验性 HTTP/2 适配器。
|
||||
**从这份 README 开始接入。** 当前版本 **`v0.12.0-preview`**,新生成项目采用根目录入口和 `config / svc / logic / handler`。可以固定版本开展业务接入;文件维护边界和已有服务迁移步骤见 [项目指南](PROJECT.md),版本变化与验收见 [发布说明](RELEASE.md)。
|
||||
|
||||
Go **1.22+**。框架不依赖 Gin,默认使用标准库网络层,提供可切换的 native HTTP/1.1 和实验性 HTTP/2 适配器。
|
||||
|
||||
响应字段、业务码、登录方式、权限规则和数据库表结构由接入项目决定。文中的 `code/msg/data`、`200/9999` 都是示例配置,可以替换。
|
||||
|
||||
@@ -22,27 +24,26 @@ GoOmni 是面向多个业务项目复用的 Go 后端框架:用 `.api` 定义
|
||||
|
||||
module 地址是 `git.yuntuo.hk/k2safe/go-omni`。先确保本机 Go 和 Git 可用,并具有仓库读取权限;使用自己的 Git 凭据管理器,不把账号或 Token 写进 module 地址。
|
||||
|
||||
以下命令在同一个终端执行。已有 `GOPRIVATE` 时,把 `git.yuntuo.hk` 追加到原来的逗号分隔列表。
|
||||
安装固定版本的 CLI,后面的命令继续使用同一终端。私有 module 加入 GOPRIVATE,保留已有配置:
|
||||
|
||||
```sh
|
||||
export GOPRIVATE=git.yuntuo.hk
|
||||
go install git.yuntuo.hk/k2safe/go-omni/cmd/go-omni@v0.11.1-preview
|
||||
export GOPRIVATE="$(go env GOPRIVATE),git.yuntuo.hk"
|
||||
go install git.yuntuo.hk/k2safe/go-omni/cmd/go-omni@v0.12.0-preview
|
||||
export PATH="$(go env GOPATH)/bin:$PATH"
|
||||
go-omni --help
|
||||
```
|
||||
|
||||
如果配置了自定义 `GOBIN`,将那个目录加入 PATH。只引用框架包、不生成项目时可以跳过 CLI 安装,直接使用下文的 `go get`。
|
||||
如果设置过 GOBIN,将该目录加入 PATH。远程 CLI 默认引用自身版本的框架,生成的 go.mod 不需要本地 replace。开发者与 CI 使用同版 CLI;框架源码开发方式见 [CLI 文档](cmd/go-omni/README.md#版本与迁移)。
|
||||
|
||||
## 新项目:生成并运行
|
||||
|
||||
在准备存放业务项目的目录执行,`./hello` 必须是新目录或空目录;把 `example.com/hello` 换成自己的 Go module 名称。
|
||||
|
||||
```sh
|
||||
go-omni api new --framework-version v0.11.1-preview \
|
||||
--module example.com/hello ./hello
|
||||
go-omni api new --module example.com/hello ./hello
|
||||
cd hello
|
||||
go mod tidy
|
||||
go run ./cmd/server
|
||||
go run .
|
||||
```
|
||||
|
||||
另开终端验证:
|
||||
@@ -59,30 +60,30 @@ curl -sS http://127.0.0.1:8080/openapi.json
|
||||
{"code":"OK","message":"success","data":{"message":"Hello Alice"},"requestId":"本次请求编号"}
|
||||
```
|
||||
|
||||
按 Ctrl+C 停止服务。项目依赖已固定为远程版本,不需要克隆框架源码或添加本地 `replace`。
|
||||
按 Ctrl+C 停止服务。进入项目目录即可 `go build .`;该示例不需要数据库或其他外部服务。
|
||||
|
||||
### 生成的项目放什么
|
||||
|
||||
```text
|
||||
hello/
|
||||
├── api/service.api # 维护接口定义,也可 import 其他 .api
|
||||
├── cmd/server/main.go # 启动、路由注册、优雅退出
|
||||
├── main.go # 生成器维护:启动、路由注册、优雅退出
|
||||
├── etc/config.yaml # 项目配置
|
||||
├── internal/
|
||||
│ ├── settings/ # 配置读取
|
||||
│ ├── servicecontext/ # 数据库、日志、外部客户端等依赖
|
||||
│ ├── config/ # 配置读取
|
||||
│ ├── svc/ # 数据库、日志、外部客户端等依赖
|
||||
│ ├── types/typesGen.go # 生成的请求与业务返回类型
|
||||
│ ├── handler/ # 生成的绑定、响应策略、路由及文档
|
||||
│ ├── service/greet/ # 在这里实现业务逻辑
|
||||
│ ├── logic/greet/ # 在这里实现业务逻辑
|
||||
│ ├── repository/greet/ # 在这里实现数据访问
|
||||
│ └── middleware/ # 声明鉴权等中间件后生成对应 hook
|
||||
├── docs/openapi.json # 生成的 OpenAPI 3.0.3
|
||||
└── .goOmni/apiManifest.json # 生成文件所有权与校验信息,一起提交 Git
|
||||
```
|
||||
|
||||
修改 `api/service.api` 后重新生成,业务写在 `internal/service`,数据访问写在 `internal/repository`,依赖在 `internal/servicecontext` 装配。声明业务错误后还会生成 `internal/apierrors/errorsGen.go`。
|
||||
修改 `api/service.api` 后重新生成,业务写在 `internal/logic`,数据访问写在 `internal/repository`,依赖在 `internal/svc` 装配。声明业务错误后还会生成 `internal/apierrors/errorsGen.go`。
|
||||
|
||||
`api new` 的问候接口可以直接运行;自定义接口新生成的 Service 和鉴权 hook 返回 **501**,需要实现后才可用。生成器不会根据 HTTP 字段猜数据库表或业务规则。
|
||||
`api new` 的问候接口可以直接运行;自定义接口新生成的 Logic 和鉴权 hook 返回 **501**,需要实现后才可用。生成器不会根据 HTTP 字段猜数据库表或业务规则。
|
||||
|
||||
### 从自己的接口定义生成
|
||||
|
||||
@@ -91,6 +92,8 @@ hello/
|
||||
```text
|
||||
syntax = "v1"
|
||||
|
||||
@app (defaultResponse: CommonResponse)
|
||||
|
||||
response CommonResponse (
|
||||
body: {"code":"${code}", "msg":"${message}", "data":"${data}"}
|
||||
codeType: int32
|
||||
@@ -126,13 +129,13 @@ service catalog-api {
|
||||
|
||||
```sh
|
||||
go-omni api validate --api catalog.api
|
||||
go-omni new --api catalog.api --framework-version v0.11.1-preview \
|
||||
go-omni new --api catalog.api \
|
||||
--module example.com/catalog ./catalog
|
||||
cd catalog
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
将生成的 `internal/service/item/getItem.go` 替换为下面的演示实现。实际业务中换成 Repository 查询,Service 返回业务数据或错误,不再手工包装公共体:
|
||||
将生成的 `internal/logic/item/getItem.go` 替换为下面的演示实现。实际业务中换成 Repository 查询,Logic 返回业务数据或错误,不再手工包装公共体:
|
||||
|
||||
```go
|
||||
package item
|
||||
@@ -144,7 +147,7 @@ import (
|
||||
"example.com/catalog/internal/types"
|
||||
)
|
||||
|
||||
func (s *Service) GetItem(ctx context.Context, req *types.GetItemReq) (*types.ItemResp, error) {
|
||||
func (s *Logic) GetItem(ctx context.Context, req *types.GetItemReq) (*types.ItemResp, error) {
|
||||
if req.ItemID != "1001" {
|
||||
return nil, apierrors.ItemNotFound()
|
||||
}
|
||||
@@ -156,7 +159,7 @@ func (s *Service) GetItem(ctx context.Context, req *types.GetItemReq) (*types.It
|
||||
|
||||
```sh
|
||||
# catalog 项目目录中启动;先停掉前面的 hello 服务,释放 8080 端口。
|
||||
go run ./cmd/server
|
||||
go run .
|
||||
# 另一个终端:
|
||||
curl -i http://127.0.0.1:8080/api/v1/items/1001
|
||||
curl -i http://127.0.0.1:8080/api/v1/items/missing
|
||||
@@ -167,24 +170,24 @@ curl -i http://127.0.0.1:8080/api/v1/items/missing
|
||||
需要 MySQL、文件存储或文件日志时,**首次生成**可以使用:
|
||||
|
||||
```sh
|
||||
go-omni new --api catalog.api --framework-version v0.11.1-preview \
|
||||
go-omni new --api catalog.api \
|
||||
--module example.com/catalogFull --database mysql --storage local \
|
||||
--log-output file --log-format json ./catalogFull
|
||||
```
|
||||
|
||||
该命令在 `catalog.api` 所在目录执行,目标仍需是新目录。数据库迁移、表结构和 Repository 由项目维护,API 模板不自动建表;MySQL DSN 通过 `GO_OMNI_DB_DSN` 提供。存储还可选 `s3`、`r2`、`oss`,按生成项目的配置说明提供桶、端点和凭据。完整装配例子见 [userService](examples/userService/README.md)。
|
||||
该命令在 `catalog.api` 所在目录执行,目标仍需是新目录。数据库迁移、表结构和 Repository 由项目维护,API 模板不自动建表;MySQL DSN 通过 `GO_OMNI_DB_DSN` 提供。存储还可选 `s3`、`r2`、`oss`,按生成项目的配置说明提供桶、端点和凭据。完整生成项目示例见 [managedService](examples/managedService/README.md)。
|
||||
|
||||
不采用 `.api` 时,也可以用 `go-omni new --framework-version v0.11.1-preview --module example.com/billing ./billing` 创建手写接口的 CRUD 示例项目;两种生成方式选择一种即可。
|
||||
`go-omni new` 与 `go-omni api new` 统一生成契约项目。需要手写项目时,可直接引用框架包;生成器不再提供另一套 CRUD 启动目录。
|
||||
|
||||
## 已有项目:按模块接入
|
||||
|
||||
在业务项目的 **go.mod 所在目录**执行:
|
||||
|
||||
```sh
|
||||
go get git.yuntuo.hk/k2safe/go-omni@v0.11.1-preview
|
||||
go get git.yuntuo.hk/k2safe/go-omni@v0.12.0-preview
|
||||
```
|
||||
|
||||
已有项目可直接复用现有目录、Service、Repository 和数据库连接,先选择一个接口接入。也可以只用 `logx`、`storage` 等包,暂时保留原来的 HTTP 框架。
|
||||
已有项目可直接复用现有目录、Service、Repository 和数据库连接,先选择一个接口接入。也可以只用 `logx`、`storage` 等包,暂时保留原来的 HTTP 框架。希望入口和 HTTP 接入都交给生成器的项目,按 [已有服务接入步骤](PROJECT.md#已有服务接入步骤) 在新目录生成后迁入业务代码。
|
||||
|
||||
下面是可独立运行的 `main.go` 示例;迁入现有项目时,把路由调用接到自己的业务服务即可。
|
||||
|
||||
@@ -377,7 +380,7 @@ return apierrors.TextTooLong("企业名称", 100)
|
||||
|
||||
### 数据库、存储及其他模块
|
||||
|
||||
依赖在启动入口或项目自己的 `internal/servicecontext` 中创建,通过构造函数传给 Service/Repository,避免每个请求都新建连接池。只注册自己拥有的资源,例如 `app.OnShutdown(db.Close)`;关闭按注册的逆序执行。
|
||||
生成项目在 `internal/svc` 中创建依赖,提供给 Logic/Repository,并用 `c.OnClose(db.Close)` 登记自有资源。生成的 main 在 HTTP 排空后关闭 svc,再关闭日志。直接使用框架的手写项目则可以用 `app.OnShutdown(db.Close)`;不要对同一资源重复登记。
|
||||
|
||||
已有项目使用 `driver.Connector` 时,直接 `database.OpenConnector(ctx, connector, database.DefaultPoolConfig())`。MySQL 等驱动的独立 TLS、Logger、时区与拨号参数由项目构造 Connector;框架负责连接池、启动 Ping、健康检查及事务。无需转成 DSN,也无需注册全局 TLS/Logger。具体示例和资源归属见 [Connector 接入](database/README.md#connector-接入v091-preview)。
|
||||
|
||||
@@ -411,7 +414,7 @@ API 项目的数据库迁移需要单独维护并显式执行;启动不会自
|
||||
例如在生成项目中切换 native:
|
||||
|
||||
```sh
|
||||
GO_OMNI_TRANSPORT=native go run ./cmd/server
|
||||
GO_OMNI_TRANSPORT=native go run .
|
||||
```
|
||||
|
||||
手写入口可用 `omni.WithTransport(omni.TransportNative)`;TLS 配置为 `omni.WithTLS(certFile, keyFile)`。native 提供 HTTP/1.1、Keep-Alive、TLS、超时、连接/请求并发上限和对象复用;HTTP/2 是单独的实验适配器,必须配置 TLS。默认 nethttp 的 TLS 支持 HTTP/1.1 与 HTTP/2。
|
||||
@@ -447,9 +450,9 @@ go-omni api generate --check
|
||||
go test ./...
|
||||
```
|
||||
|
||||
`Gen.go`、`docs/openapi.json` 和 manifest 由生成器管理,手动修改会报告冲突。Service、Repository、中间件实现、main、配置和依赖装配属于项目,重复生成保留手写内容;契约改变后仍需自行调整业务签名并通过编译。将 `.api`、生成文件和 `.goOmni/apiManifest.json` 一起提交,CI 可运行 `generate --check` 检查是否同步。
|
||||
`main.go`、`Gen.go`、`docs/openapi.json` 和 manifest 由生成器管理,手动修改会报告冲突。Logic、Repository、中间件实现、配置和依赖装配属于项目,重复生成保留手写内容。契约变化会提示受影响的 Logic 文件和 DTO 字段,明确的签名错误会给出原签名与期望签名;生成后 `--check` 仍能检出未修复的问题。将 `.api`、生成文件和 `.goOmni/apiManifest.json` 一起提交,CI 同时运行 `generate --check` 与 `go test ./...`。详见 [契约变更提示与检查边界](PROJECT.md#契约变更提示)。
|
||||
|
||||
升级时先安装目标版本的 CLI,再在业务 module 中 `go get` **同一版本**;API 项目随后执行上述生成与测试步骤,手写项目只需依赖升级及业务回归。`v0.11.1-preview` 的变化、迁移边界和验收记录见 [发布说明](RELEASE.md)。
|
||||
CLI 与业务 module 固定使用 `v0.12.0-preview`。新布局不兼容旧 manifest;旧试验项目需在新目录生成并搬入业务文件,不能直接覆盖手写入口。新布局内部升级再执行上述生成与测试步骤,手写框架项目只需依赖升级及业务回归。版本变化、迁移边界和验收记录见 [发布说明](RELEASE.md)。
|
||||
|
||||
## 按需深入
|
||||
|
||||
@@ -457,8 +460,9 @@ go test ./...
|
||||
| --- | --- |
|
||||
| `.api` 类型、参数绑定、错误、鉴权和生成规则 | [API 开发指南](API.md) |
|
||||
| 公共响应体、提示优先级、独立回调协议 | [响应参考](RESPONSE.md) |
|
||||
| CLI 完整参数、本地框架开发和模块脚手架 | [CLI](cmd/go-omni/README.md) |
|
||||
| 完整 API 业务项目 | [userService](examples/userService/README.md) |
|
||||
| CLI 完整参数、本地框架开发与迁移 | [CLI](cmd/go-omni/README.md) |
|
||||
| 当前生成项目:Go 错误目录、上传、回调和下载 | [managedService](examples/managedService/README.md) |
|
||||
| 数据库/事务业务参考(旧目录示例) | [userService](examples/userService/README.md) |
|
||||
| 手写接口分层示例 | [reference](examples/reference/README.md) |
|
||||
| 框架成熟度、历史变更 | [路线图](ROADMAP.md)、[更新记录](CHANGELOG.md) |
|
||||
| 网络性能、测试条件与适用范围 | [性能说明](PERFORMANCE.md)、[HTTP/2 验收](transport/native/HTTP2.md) |
|
||||
|
||||
Reference in New Issue
Block a user