4 层 API

Zeus 用 4 层 API 覆盖不同用户。不允许越层泄漏概念——L1 用户不应感知 Component / Container / Lifecycle 等内部接口名。

层级概览

用户入口暴露概念目标
L1学习者 / 单进程 demozeus.Run(cfg, handler)App + Config5 行启动
L2个人开发者 / 配置驱动zeus.Run(cfgWithRegistry, handler)App + Config + Registry(URL)改配置即可
L3小团队 / 代码定制app.NewApp(opts ...AppOption)Server + Logger + Registry + …类型装配
L4定制需求 / 完全控制components.NewApp(comps ...any)全部组件接口永久逃生通道

L1:5 行启动

1app.Run(&app.Config{Port: 8080}, http.HandlerFunc(handler))

仅暴露 AppConfig 两个概念。其余全部默认装配。

L2:URL scheme 驱动

1import _ "github.com/go-zeus/zeus/plugins/registry/etcd"
2import _ "github.com/go-zeus/zeus/plugins/cache/redis"
3
4app.Run(&app.Config{
5    Port:     8080,
6    Registry: "etcd://localhost:2379",
7    Cache:    "redis://localhost:6379",
8}, handler)

L2 用 URL scheme(etcd:// / memory:// / k8s:// / redis://)代替直接 import 实现包的细节构造。

L3:类型装配

1a := app.NewApp(
2    app.AddServer(http.NewHTTP(http.Port(8080), http.Mux(handler))),
3    app.WithRegistry(memory.New()),
4    app.WithMiddleware(recovery.New()),
5    app.WithServiceCluster("canary"),
6)
7a.Run()

L3 是 L4 的"语法糖",返回 *components.App,底层 100% 复用 Container/Lifecycle。

Option 清单:AddServer / WithLogger / WithRegistry / WithMeter / WithTracer / WithMiddleware / WithServiceName / WithServiceCluster / WithServiceIP / WithStopTimeout / WithComponent / WithCacheURL / WithDatabaseURL / WithMQURL

L4:声明式组件

1app := components.NewApp(
2    components.NewLogComponent(slog.NewSlog()),
3    components.NewRegistryComponent(memory.New()),
4    components.NewServerComponent(http.NewHTTP(http.Mux(mux))),
5    components.NewServiceComponent(),
6)
7app.Run()

L4 完整保留,作为永久逃生通道。组件声明依赖 → 拓扑排序 → 按序 Provide → OnStart → 逆序 OnStop。

混用(关键卖点)

L3 可与 L4 混用,参数末尾直接追加 L4 Component:

1a := app.NewApp(
2    app.AddServer(http.NewHTTP()),
3    app.WithMiddleware(recovery.New()),
4    components.NewCacheComponent(myCache),       // L4 组件
5    components.NewJobComponent(scheduler),       // L4 组件
6)

何时升级层级

场景推荐层级
Demo / PoCL1
单进程生产L1 或 L2
多实例 + 注册中心L2
自定义中间件链L3
多 Server(HTTP+gRPC 同进程)L3 或 L4
完全控制组件生命周期L4

与 L1 的关键差异

  • L1 自动包装 requestid → accesslog → recovery 中间件(注:/health 是路由端点而非中间件;/metrics 非默认装配,需 L3 WithMeter 启用);L3/L4 不自动包装
  • 原因:L3/L4 用户已直接构造 Server,对中间件链有完全控制
  • L3/L4 默认链需用户显式:WithMiddleware(recovery.New())

禁止规则

  1. L1/L2 文档不能出现 Component / Container / Lifecycle / Provide / Instance 等内部接口名
  2. L1 必须支持 0 配置启动
  3. 新增功能先评估能否做默认,再考虑做成 Option
  4. 类型推断优于显式选择