Wails2 系列 03:后端服务层:把可绑定 API 按业务域拆开
cbowen

适合读者

适合已经会用 Wails Bind 暴露 Go 方法,但项目中绑定方法开始变多的开发者。

问题场景

很多 Wails 项目最初只有一个 App 结构体:

1
type App struct{}

然后所有方法都往里面加:获取配置、保存主题、读取待办、导入文件、检查更新、发送通知、同步用户资料。这个写法在功能少时没问题,但方法数量一多,前端只会看到一个什么都能做的对象。

这会带来两个问题:前端不知道某个能力属于哪个业务域;后端也不知道新逻辑应该放在哪里。

项目观察

当前项目把 Wails 后端服务放在 internal/service 下,并按业务域拆分,例如应用能力、学生、待办、反馈、AI 等。这种结构传达了一个重要信号:Wails Bind 不是只能绑定一个大对象,也可以绑定多个有清晰边界的服务。

这些服务通常有自己的构造函数,并在启动时接收必要依赖,例如存储对象、配置对象或运行时 context。

拆分原则

后端服务层的核心不是“文件夹越多越好”,而是前端调用模型要清楚。

推荐按业务域拆分服务:

  • AppService:应用信息、窗口行为、更新、通知。
  • SettingsService:偏好设置、主题、启动选项。
  • TodoService:待办的增删改查。
  • ProfileService:用户资料相关能力。

不要按技术动作拆得太碎,例如 ReadServiceWriteServiceDialogService。前端关心的是业务用例,而不是内部实现方式。

改造示例

不推荐把所有方法都塞到一个对象:

1
2
3
4
5
6
type App struct{}

func (a *App) GetTheme() string { return "" }
func (a *App) SaveTodo(title string) {}
func (a *App) ExportData() string { return "" }
func (a *App) CheckForUpdate() string { return "" }

可以按业务域拆开:

1
2
3
4
5
6
7
8
9
10
11
12
type SettingsService struct {
config *Config
}

func (s *SettingsService) GetTheme() string {
return s.config.Theme
}

func (s *SettingsService) SetTheme(theme string) error {
s.config.Theme = theme
return s.config.Save()
}
1
2
3
4
5
6
7
type TodoService struct {
store TodoStore
}

func (s *TodoService) ListToday() ([]Todo, error) {
return s.store.ListByDate(time.Now())
}

入口只负责绑定它们:

1
2
3
4
5
Bind: []any{
settingsService,
todoService,
appService,
}

前端调用时也会更清晰:设置找设置服务,待办找待办服务,应用级能力找应用服务。

检查清单

  • 每个绑定服务是否有明确业务域?
  • 服务名称是否能让前端开发者猜到它负责什么?
  • 单个服务是否暴露了过多不相关方法?
  • 服务是否通过构造函数接收依赖?
  • 绑定方法是否面向前端用例,而不是内部工具函数?
  • 新增功能时,是否能判断它应该进入已有服务还是新建服务?

下一篇

下一篇会把视角放到数据:业务服务不应该到处直接读写文件或数据库,存储层和配置层需要独立出来。

 评论
评论插件加载失败
正在加载评论插件