OpenTreeHole Backend Project
开源树洞后端综合体
- 单体架构,避免重复代码
- 基于 nunu 的框架设计,分层架构更清晰
- 基于 wire 的依赖注入设计
构建工具
构建本项目
本地构建并运行
# 克隆本项目
git clone https://github.com/OpenTreeHole/backend.git
cd chatdan_backend
# 安装 swaggo 并且生成 API 文档
go install github.com/swaggo/swag/cmd/swag@latest
swag init -d cmd,internal/handler,internal/schema -p snakecase -o internal\docs
# 将 config/config_default.json 复制为 config/config.json, 并且按照需求修改配置,否则会使用默认配置
cp config/config_default.json config/config.json
# 运行
go run ./cmd
# 使用 nunu 运行本项目,支持文件更新热重启
go install github.com/go-nunu/nunu@latest
nunu run
API 文档详见启动项目之后的 http://localhost:8000/docs
生产部署
使用 docker 部署
docker run -d \
--name opentreehole_backend \
-p 8000:8000 \
-e MODULES_CURRICULUM_BOARD=true \
-v opentreehole_data:/app/data \
-v opentreehole_config:/app/config \
opentreehole/backend:latest
使用 docker-compose 部署
version: '3'
services:
backend:
image: opentreehole/backend:latest
restart: unless-stopped
environment:
- DB_TYPE=mysql
- DB_URL=opentreehole:${MYSQL_PASSWORD}@tcp(mysql:3306)/opentreehole?parseTime=true&loc=Asia%2FShanghai
- CACHE_TYPE=redis
- CACHE_URL=redis:6379
- MODULES_CURRICULUM_BOARD=true
volumes:
- data:/app/data
- config:/app/config
mysql:
image: mysql:8.0.34
restart: always
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=opentreehole
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_DATABASE=opentreehole
- TZ=Asia/Shanghai
volumes:
- mysql_data:/var/lib/mysql
- mysql_config:/etc/mysql/conf.d
redis:
container_name: fduhole_redis
image: redis:7.0.11-alpine
restart: always
volumes:
data:
config:
环境变量:
TZ
: 生产环境默认Asia/Shanghai
MODE
: 开发环境默认dev
, 生产环境默认production
, 可选test
,bench
LOG_LEVEL
: 开发环境默认debug
, 生产环境默认info
, 可选warn
,error
,panic
,fatal
PORT
: 默认 8000DB_TYPE
: 默认sqlite
, 可选mysql
,postgres
DB_DSN
: 默认data/sqlite.db
MODULES_{AUTH/NOTIFICATION/TREEHOLE/CURRICULUM_BOARD}
: 开启模块,默认为false
数据卷:
/app/data
: 数据库文件存放位置/app/config
: 配置文件存放位置
注:环境变量设置仅在程序启动时生效,后续可以修改 config/config.json
动态修改配置
开发指南
- 使用 wire 作为依赖注入框架。如果创建了新的依赖项,需要在
cmd/wire/wire.go
中注册依赖项的构造函数,之后运行nunu wire
生成新的cmd/wire/wire_gen.go
- 基于数据流的分层架构。本项目分层为
handler
->service
->repository
。hander
结构必须组合*Handler
类型。handler
只负责接口接收、鉴权和响应,并且把控制权交给service
service
结构必须组合Service
接口。service
负责主要业务逻辑,其中数据库操作调用repository
的接口,Service.Transaction
方法可以把多个repository
接口调用合并到一个事务中。repository
结构必须组合Repository
接口。与数据库、缓存的CURD操作相关的必须放在repository
的绑定函数中实现。
- 分离接口请求和响应模型
schema
和数据库模型model
。handler
接受和发送都只能使用schema
,service
负责schema
和model
的转换,repository
只使用model
- 如果
model
和schema
之间的转换逻辑冗余,可以在schema
中定义类似func (s *Schema) FromModel(m *Model) *Schema
和func (s *Schema) ToModel() *Model
绑定函数,保证模块的引用顺序是schema
->model
,避免循环引用。 - 避免在
model
和schema
中作数据库、缓存的CURD,这些都应该在service
层中调用repository
层的接口来完成。如果模型转换时需要用到数据库接口,需要作为函数参数传入转换函数。
计划路径
- 迁移旧项目到此处
贡献列表
联系方式
JingYiJun - jingyijun@fduhole.com
Danxi-Dev - dev@fduhole.com