RRuna

工程结构

推荐的 Runa 应用目录组织

Runa 不强制目录结构。小项目可以只有一个 main.go,项目变大后,建议把入口、业务模块、配置、数据目录分开。

最小项目可以很简单

刚开始可以这样:

my-app/
  main.go
  go.mod

当路由、命令、任务和业务代码变多后,再拆目录。

推荐的业务项目结构

my-app/
  cmd/app/main.go
  app/
    user/
      module.go
      routes.go
      commands.go
    order/
      module.go
      routes.go
      jobs.go
  config/
    app.toml
    cache.toml
    queue.toml
  data/
  public/
  go.mod

每个目录的职责:

目录 放什么
cmd/app 程序入口,只负责创建应用和装载能力
app 你的业务模块,比如用户、订单、支付
config TOML 配置文件
data 运行时可写文件,比如本地缓存、上传临时文件
public 公开静态资源

入口目录只负责启动应用

cmd/app/main.go 只做装配,不写具体业务逻辑:

package main

import (
    "context"

    "example.com/my-app/app/order"
    "example.com/my-app/app/user"

    "github.com/duxweb/runa"
    "github.com/duxweb/runa/cache"
    "github.com/duxweb/runa/route"
)

func main() {
    app := runa.New(
        runa.ConfigPath("config"),
        runa.DataPath("data"),
        runa.PublicPath("public"),
    )

    app.Install(
        route.Provider(route.Addr(":8080")),
        cache.Provider(),
    )

    app.Module(
        user.Module{},
        order.Module{},
    )

    if err := app.Run(context.Background()); err != nil {
        panic(err)
    }
}

这样做的好处是:入口文件只看得到应用用了哪些能力和业务模块,不会被具体 handler、SQL、任务逻辑塞满。

业务逻辑通过 Module 接入

比如 app/user/module.go

package user

import (
    "context"

    "github.com/duxweb/runa/provider"
    "github.com/duxweb/runa/route"
)

type Module struct {
    provider.ModuleBase
}

func (Module) Name() string { return "user" }

func (Module) Register(ctx context.Context, app provider.Context) error {
    route.Default().Get("/users", listUsers)
    return app.RegisterCommand(SyncUsersCommand{})
}

Module 是业务入口。它适合注册当前业务域的路由、命令、队列任务、事件监听等内容。

配置按能力和模块拆分

配置文件使用 TOML。文件名就是配置作用域:

config/cache.toml   -> cache 配置
config/queue.toml   -> queue 配置
config/user.toml    -> user 模块配置

环境配置可以使用这种命名:

config/app.production.toml
config/cache.production.toml

当前环境由 runa.Env("production") 或环境变量决定。

什么时候需要拆目录

可以按这个节奏来:

  • 只有几个接口时,先放 main.go
  • 出现多个业务域时,拆 app/userapp/order
  • 出现命令、任务、事件监听时,放进对应业务模块
  • 配置变多后,按能力和业务模块拆成多个 TOML 文件

不要为了“看起来标准”过早拆很多目录。目录结构是为了降低复杂度,不是为了增加仪式感。

常见错误

一开始就拆太多目录

小项目可以先从 main.go 开始。目录是为了解决复杂度,不是为了形式。

main.go 写太多业务逻辑

入口文件只做装配。业务路由、命令、任务和事件监听放进 Module。

配置文件混成一个大文件

配置变多后,按能力和业务模块拆分,比如 cache.tomlqueue.tomluser.toml

编辑此页