feat: 完善后端脚手架基础能力
This commit is contained in:
@@ -1,218 +1,497 @@
|
||||
# Skeleton
|
||||
# Go Skeleton
|
||||
|
||||
一个基于 Go 的后端脚手架项目,内置 Gin、GORM、Redis、JWT、Atlas 迁移管理和 `gin-docs` 自动接口文档,适合作为新项目起点。
|
||||
面向实际项目开发的 Go Web API 脚手架。它将 HTTP、WebSocket、认证、数据库迁移、缓存、接口文档和可观测性组织成可继续扩展的基础工程。
|
||||
|
||||
> 当前模块名为 `skeleton`。创建新项目后,请先使用初始化脚本替换成自己的 Go module path。
|
||||
|
||||
## 特性
|
||||
|
||||
- Gin HTTP 框架
|
||||
- 模块化路由组织
|
||||
- 统一响应结构
|
||||
- JWT 认证中间件
|
||||
- CORS、日志、恢复、错误记录中间件
|
||||
- PostgreSQL 和 Redis 初始化封装
|
||||
- Atlas + GORM Schema 迁移管理
|
||||
- `gin-docs` 自动扫描接口并生成 OpenAPI 文档
|
||||
- 预留 WebSocket 挂载点
|
||||
- Gin HTTP 路由及公开、JWT 私有路由分组
|
||||
- PostgreSQL、MySQL、SQLite 三种 GORM 数据库驱动
|
||||
- 按 SQL 方言隔离的 Atlas 数据库迁移
|
||||
- 可选 Redis,以及 JWT 撤销记录存储
|
||||
- Access Token、Refresh Token、刷新轮换和注销示例
|
||||
- WebSocket 房间、广播、连接管理和心跳示例
|
||||
- Swaggo OpenAPI 文档和 Swagger UI
|
||||
- Zap 结构化日志、请求 ID、Prometheus 指标
|
||||
- OpenTelemetry OTLP HTTP 链路追踪
|
||||
- Dockerfile、Docker Compose、GitHub Actions
|
||||
- Linux、macOS、Windows amd64 交叉编译
|
||||
|
||||
## 目录
|
||||
|
||||
- [快速开始](#快速开始)
|
||||
- [项目结构](#项目结构)
|
||||
- [配置](#配置)
|
||||
- [HTTP API](#http-api)
|
||||
- [WebSocket](#websocket)
|
||||
- [数据库迁移](#数据库迁移)
|
||||
- [接口文档](#接口文档)
|
||||
- [可观测性](#可观测性)
|
||||
- [测试](#测试)
|
||||
- [编译](#编译)
|
||||
- [Docker](#docker)
|
||||
- [开发新模块](#开发新模块)
|
||||
- [安全说明](#安全说明)
|
||||
- [贡献](#贡献)
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 能力 | 实现 |
|
||||
| --- | --- |
|
||||
| HTTP | Gin |
|
||||
| WebSocket | Gorilla WebSocket |
|
||||
| ORM | GORM |
|
||||
| 数据库 | PostgreSQL / MySQL / SQLite |
|
||||
| 数据迁移 | Atlas + Atlas GORM Provider |
|
||||
| 缓存 | Redis,可选 |
|
||||
| 认证 | JWT HS256 + bcrypt |
|
||||
| API 文档 | Swaggo / Swagger UI |
|
||||
| 日志 | Zap |
|
||||
| 指标 | Prometheus |
|
||||
| Trace | OpenTelemetry OTLP HTTP |
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 安装依赖
|
||||
### 环境要求
|
||||
|
||||
- Go 1.25+
|
||||
- Atlas CLI,仅执行数据库迁移时需要
|
||||
- Swag CLI,仅重新生成 OpenAPI 文档时需要
|
||||
- Docker,可选
|
||||
- C 编译器,使用 SQLite 时需要
|
||||
|
||||
### 1. 创建自己的项目
|
||||
|
||||
```bash
|
||||
go mod tidy
|
||||
git clone https://gitea.xchoumc.online/xchou/go-skeleton.git
|
||||
cd go-skeleton
|
||||
./scripts/init.sh github.com/yourname/your-project
|
||||
```
|
||||
|
||||
### 2. 配置环境
|
||||
### 2. 使用 SQLite 快速运行
|
||||
|
||||
修改 [`config/app.yaml`](config/app.yaml):
|
||||
修改 `config/app.yaml`:
|
||||
|
||||
- `app`:主机、端口、版本、环境、时区
|
||||
- `logger`:日志级别与输出方式
|
||||
- `database`:PostgreSQL 连接信息
|
||||
- `redis`:Redis 连接信息
|
||||
- `jwt`:Token 配置
|
||||
```yaml
|
||||
database:
|
||||
driver: sqlite
|
||||
sqlite_path: data/skeleton.db
|
||||
|
||||
### 3. 启动项目
|
||||
|
||||
```bash
|
||||
go run .
|
||||
```
|
||||
|
||||
默认监听地址由配置决定,示例为 `0.0.0.0:8080`。
|
||||
|
||||
## 接口文档
|
||||
|
||||
项目在启动时通过 `gin-docs` 自动挂载接口文档,无需手写 Swagger 注释。
|
||||
|
||||
默认文档地址:
|
||||
|
||||
- `/docs`
|
||||
|
||||
常见输出:
|
||||
|
||||
- `/docs/openapi.json`
|
||||
- `/docs/openapi.yaml`
|
||||
- `/docs/export/postman`
|
||||
- `/docs/export/insomnia`
|
||||
|
||||
文档会根据 Gin 路由和 GORM 模型自动推断生成。
|
||||
|
||||
## 路由结构
|
||||
|
||||
所有 API 默认挂载在 `/api` 下。
|
||||
|
||||
### 公开接口
|
||||
|
||||
- `GET /api/ping`
|
||||
- `GET /api/health`
|
||||
- `GET /api/example/hello`
|
||||
|
||||
### 私有接口
|
||||
|
||||
- `/api/private/*`
|
||||
|
||||
该分组默认挂载 JWT 认证中间件,适合后续需要登录态的业务接口。
|
||||
|
||||
### WebSocket
|
||||
|
||||
- `routes/ws/` 预留 WebSocket 扩展入口
|
||||
|
||||
## 模板初始化
|
||||
|
||||
如果这是通过 GitHub Template 生成的新仓库,可以直接运行初始化脚本,把 `go.mod` 和源码里的包路径一次性改掉:
|
||||
|
||||
```bash
|
||||
./scripts/init.sh github.com/yourname/yourrepo
|
||||
```
|
||||
|
||||
脚本会自动完成:
|
||||
|
||||
- 更新 `go.mod` 的 module 名称
|
||||
- 替换源码中的旧包路径
|
||||
- 执行 `go mod tidy`
|
||||
|
||||
## 项目结构
|
||||
|
||||
```text
|
||||
.
|
||||
├── main.go
|
||||
├── config/
|
||||
├── database/
|
||||
├── middlewares/
|
||||
├── models/
|
||||
├── modules/
|
||||
├── routes/
|
||||
├── utils/
|
||||
├── cmd/migrate/
|
||||
├── atlas.hcl
|
||||
├── atlas_loader.go
|
||||
└── config/app.yaml
|
||||
```
|
||||
|
||||
## 主要目录说明
|
||||
|
||||
- [`main.go`](main.go):启动入口,负责初始化配置、日志、JWT、数据库、Redis、路由和文档
|
||||
- [`routes/`](routes):REST 和 WebSocket 路由挂载
|
||||
- [`middlewares/`](middlewares):日志、CORS、JWT、恢复处理
|
||||
- [`database/`](database):PostgreSQL 和 Redis 连接封装
|
||||
- [`modules/`](modules):业务模块示例
|
||||
- [`models/`](models):GORM 模型
|
||||
- [`utils/`](utils):响应、分页、时区等通用工具
|
||||
- [`cmd/migrate/`](cmd/migrate/main.go):迁移命令输出入口
|
||||
|
||||
## 数据库迁移
|
||||
|
||||
项目集成了 Atlas + GORM Provider,用于根据模型生成迁移。
|
||||
|
||||
### 相关文件
|
||||
|
||||
- [`atlas.hcl`](atlas.hcl)
|
||||
- [`atlas_loader.go`](atlas_loader.go)
|
||||
|
||||
### 安装 Atlas
|
||||
|
||||
```bash
|
||||
brew install ariga/tap/atlas
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```bash
|
||||
go install ariga.io/atlas/cmd/atlas@latest
|
||||
```
|
||||
|
||||
### 迁移命令
|
||||
|
||||
`cmd/migrate` 会根据参数输出对应的 Atlas 命令。
|
||||
|
||||
查看状态:
|
||||
|
||||
```bash
|
||||
go run cmd/migrate/main.go -action status
|
||||
```
|
||||
|
||||
生成迁移:
|
||||
|
||||
```bash
|
||||
go run cmd/migrate/main.go -action diff
|
||||
go run cmd/migrate/main.go -action diff -name create_users
|
||||
redis:
|
||||
enabled: false
|
||||
```
|
||||
|
||||
应用迁移:
|
||||
|
||||
```bash
|
||||
export DATABASE_URL='sqlite://data/skeleton.db'
|
||||
export DATABASE_DEV_URL='sqlite://dev?mode=memory&_fk=1'
|
||||
go run cmd/migrate/main.go -action apply
|
||||
```
|
||||
|
||||
验证迁移:
|
||||
启动服务:
|
||||
|
||||
```bash
|
||||
go run cmd/migrate/main.go -action validate
|
||||
go run .
|
||||
```
|
||||
|
||||
### 环境变量
|
||||
默认服务地址:
|
||||
|
||||
`atlas.hcl` 使用以下环境变量:
|
||||
| 服务 | 地址 |
|
||||
| --- | --- |
|
||||
| API | `http://localhost:8080/api` |
|
||||
| Swagger UI | `http://localhost:8080/docs/index.html` |
|
||||
| Prometheus Metrics | `http://localhost:8080/metrics` |
|
||||
| WebSocket | `ws://localhost:8080/api/ws` |
|
||||
|
||||
- `DATABASE_URL`
|
||||
- `DATABASE_DEV_URL`
|
||||
## 项目结构
|
||||
|
||||
## 扩展新模块
|
||||
```text
|
||||
.
|
||||
├── main.go # 应用启动与优雅关闭
|
||||
├── config/ # YAML、环境变量及配置校验
|
||||
├── database/ # GORM、Redis、Token 撤销和迁移封装
|
||||
├── middlewares/ # JWT、日志、CORS、指标、Request ID
|
||||
├── models/ # GORM 数据模型
|
||||
├── modules/
|
||||
│ ├── auth/ # 注册、登录、刷新和注销示例
|
||||
│ ├── example/ # REST 业务模块示例
|
||||
│ └── ws/ # WebSocket Hub、Client 和消息协议
|
||||
├── observability/ # OpenTelemetry 初始化
|
||||
├── routes/
|
||||
│ ├── rest/ # REST 路由注册器
|
||||
│ └── ws/ # WebSocket 路由挂载
|
||||
├── docs/ # Swag 自动生成文件
|
||||
├── migrations/
|
||||
│ ├── postgres/
|
||||
│ ├── mysql/
|
||||
│ └── sqlite/
|
||||
├── tools/atlas-loader/ # 独立 Atlas GORM Schema 工具模块
|
||||
├── scripts/
|
||||
│ ├── init.sh # 修改 Go module path
|
||||
│ └── build.sh # 多平台 amd64 构建
|
||||
├── Dockerfile
|
||||
├── docker-compose.yml
|
||||
└── Makefile
|
||||
```
|
||||
|
||||
新增业务时建议按以下方式组织:
|
||||
## 配置
|
||||
|
||||
1. 在 `modules/` 下创建新模块目录
|
||||
2. 在 `routes/rest/` 中注册路由
|
||||
3. 公共接口挂到公开路由组
|
||||
4. 需要登录态的接口挂到 `/api/private`
|
||||
5. 如有模型变更,先更新 `models/`,再生成迁移
|
||||
|
||||
## 示例模块
|
||||
|
||||
项目内置 `modules/example/` 作为参考实现,包含 controller、service 和 response 结构。
|
||||
|
||||
示例接口:
|
||||
应用默认读取 `config/app.yaml`。使用其他配置文件:
|
||||
|
||||
```bash
|
||||
GET /api/example/hello
|
||||
export SKELETON_CONFIG=config/app.yaml
|
||||
```
|
||||
|
||||
返回示例:
|
||||
环境变量优先级高于 YAML。生产环境应使用部署平台的 Secret 管理能力注入凭据。
|
||||
|
||||
### 应用和日志
|
||||
|
||||
| 环境变量 | 说明 |
|
||||
| --- | --- |
|
||||
| `APP_HOST`、`APP_PORT` | HTTP 监听地址 |
|
||||
| `APP_VERSION` | 应用版本 |
|
||||
| `APP_ENVIRONMENT` | `development` 或 `production` |
|
||||
| `APP_DEBUG` | Gin 调试模式 |
|
||||
| `APP_TIMEZONE` | IANA 时区名称 |
|
||||
| `LOG_LEVEL` | `debug`、`info`、`warn`、`error` |
|
||||
| `LOG_FORMAT` | `console` 或 `json` |
|
||||
| `LOG_OUTPUT` | `stdout` 或 `file` |
|
||||
|
||||
### 数据库
|
||||
|
||||
| 环境变量 | 说明 |
|
||||
| --- | --- |
|
||||
| `DATABASE_DRIVER` | `postgres`、`mysql` 或 `sqlite` |
|
||||
| `DATABASE_DSN` | 完整连接串,优先于其他连接参数 |
|
||||
| `DATABASE_HOST`、`DATABASE_PORT` | 服务端数据库地址 |
|
||||
| `DATABASE_USERNAME`、`DATABASE_PASSWORD` | 数据库凭据 |
|
||||
| `DATABASE_NAME` | 数据库名称 |
|
||||
| `DATABASE_SSLMODE` | PostgreSQL SSL 模式 |
|
||||
| `DATABASE_SQLITE_PATH` | SQLite 文件路径 |
|
||||
| `DATABASE_MAX_IDLE_CONNS` | 最大空闲连接数 |
|
||||
| `DATABASE_MAX_OPEN_CONNS` | 最大连接数 |
|
||||
| `DATABASE_CONN_MAX_LIFETIME` | 连接最大存活分钟数 |
|
||||
|
||||
未设置 `database.driver` 时默认使用 PostgreSQL。SQLite 会创建数据文件父目录,并默认限制为单连接。
|
||||
|
||||
### Redis、JWT 和可观测性
|
||||
|
||||
| 环境变量 | 说明 |
|
||||
| --- | --- |
|
||||
| `REDIS_ENABLED` | 是否启用 Redis |
|
||||
| `REDIS_HOST`、`REDIS_PORT`、`REDIS_PASSWORD` | Redis 连接信息 |
|
||||
| `JWT_SECRET` | HS256 签名密钥 |
|
||||
| `JWT_ACCESS_EXPIRE_MINUTES` | Access Token 有效分钟数 |
|
||||
| `JWT_REFRESH_EXPIRE_HOURS` | Refresh Token 有效小时数 |
|
||||
| `METRICS_ENABLED`、`METRICS_PATH` | Prometheus 指标开关和路径 |
|
||||
| `TRACING_ENABLED` | 是否启用 OpenTelemetry |
|
||||
| `OTEL_SERVICE_NAME` | Trace 服务名 |
|
||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP HTTP 地址,如 `localhost:4318` |
|
||||
| `OTEL_EXPORTER_OTLP_INSECURE` | 是否使用明文 OTLP |
|
||||
|
||||
生产模式会拒绝默认或少于 32 个字符的 JWT 密钥。
|
||||
|
||||
## HTTP API
|
||||
|
||||
| 方法 | 路径 | 认证 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `GET` | `/api/ping` | 否 | 进程存活检查 |
|
||||
| `GET` | `/api/health` | 否 | 数据库和可选 Redis readiness 检查 |
|
||||
| `GET` | `/api/example/hello` | 否 | REST 模块示例 |
|
||||
| `POST` | `/api/auth/register` | 否 | 注册示例用户 |
|
||||
| `POST` | `/api/auth/login` | 否 | 获取 Token Pair |
|
||||
| `POST` | `/api/auth/refresh` | 否 | 轮换 Refresh Token |
|
||||
| `POST` | `/api/private/auth/logout` | Bearer | 撤销 Access/Refresh Token |
|
||||
| `GET` | `/api/ws` | 否 | WebSocket 握手入口 |
|
||||
|
||||
完整请求和响应模型请查看 Swagger UI。
|
||||
|
||||
### 认证示例
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/auth/register \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"username":"demo","password":"change-me-123"}'
|
||||
|
||||
curl -X POST http://localhost:8080/api/auth/login \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"username":"demo","password":"change-me-123"}'
|
||||
```
|
||||
|
||||
启用 Redis 时,Token 撤销记录存储在 Redis,适合多实例部署;关闭 Redis 时使用进程内存,仅适合开发或单实例部署。
|
||||
|
||||
## WebSocket
|
||||
|
||||
连接端点:
|
||||
|
||||
```text
|
||||
ws://localhost:8080/api/ws?room=lobby&client_id=demo
|
||||
```
|
||||
|
||||
查询参数:
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `room` | 否 | 房间名,默认 `lobby`,最多 64 个字符 |
|
||||
| `client_id` | 否 | 客户端标识;未提供时服务端生成 |
|
||||
|
||||
使用 `websocat`:
|
||||
|
||||
```bash
|
||||
websocat 'ws://localhost:8080/api/ws?room=lobby&client_id=terminal-1'
|
||||
```
|
||||
|
||||
发送消息:
|
||||
|
||||
```json
|
||||
{"type":"message","data":"hello websocket"}
|
||||
```
|
||||
|
||||
服务端事件:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"message": "hello from skeleton example"
|
||||
}
|
||||
"type": "message",
|
||||
"room": "lobby",
|
||||
"client_id": "terminal-1",
|
||||
"data": "hello websocket",
|
||||
"timestamp": "2026-08-09T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## 默认配置
|
||||
事件类型:
|
||||
|
||||
`config/app.yaml` 提供了可直接运行的本地示例配置。程序启动时会自动补充未填写的默认值,方便快速开发。
|
||||
| 类型 | 说明 |
|
||||
| --- | --- |
|
||||
| `welcome` | 当前客户端连接成功 |
|
||||
| `message` | 房间广播消息 |
|
||||
| `presence` | 客户端加入或离开 |
|
||||
| `error` | 消息格式或类型错误 |
|
||||
|
||||
## 说明
|
||||
浏览器示例:
|
||||
|
||||
这个脚手架的目标不是预置所有业务,而是把通用基础设施先搭好,方便后续按模块扩展。
|
||||
```javascript
|
||||
const socket = new WebSocket(
|
||||
"ws://localhost:8080/api/ws?room=lobby&client_id=browser-1"
|
||||
);
|
||||
|
||||
socket.onmessage = (event) => console.log(JSON.parse(event.data));
|
||||
socket.onopen = () => {
|
||||
socket.send(JSON.stringify({ type: "message", data: "hello" }));
|
||||
};
|
||||
```
|
||||
|
||||
WebSocket 实现包含:
|
||||
|
||||
- 按房间隔离广播
|
||||
- 在线连接数量
|
||||
- 单连接一个 reader 和一个 writer
|
||||
- Ping/Pong 心跳与读取超时
|
||||
- 8 KiB 单消息限制
|
||||
- 有界发送队列和慢客户端清理
|
||||
- 安全的默认同源 Origin 校验
|
||||
|
||||
当前 Hub 是单进程内存实现。多实例部署时,应在 `modules/ws/hub.go` 接入 Redis Pub/Sub、NATS 或其他消息系统。
|
||||
|
||||
## 数据库迁移
|
||||
|
||||
安装 Atlas:
|
||||
|
||||
```bash
|
||||
brew install ariga/tap/atlas
|
||||
# 或
|
||||
go install ariga.io/atlas/cmd/atlas@latest
|
||||
```
|
||||
|
||||
设置当前数据库和开发数据库 URL:
|
||||
|
||||
```bash
|
||||
# PostgreSQL
|
||||
export DATABASE_URL='postgres://user:pass@localhost:5432/app?sslmode=disable'
|
||||
export DATABASE_DEV_URL='docker://postgres/17/dev'
|
||||
|
||||
# MySQL
|
||||
export DATABASE_URL='mysql://user:pass@localhost:3306/app'
|
||||
export DATABASE_DEV_URL='docker://mysql/8/dev'
|
||||
|
||||
# SQLite
|
||||
export DATABASE_URL='sqlite://data/app.db'
|
||||
export DATABASE_DEV_URL='sqlite://dev?mode=memory&_fk=1'
|
||||
```
|
||||
|
||||
常用命令:
|
||||
|
||||
```bash
|
||||
# 状态
|
||||
go run cmd/migrate/main.go -action status
|
||||
|
||||
# 根据 GORM 模型生成迁移
|
||||
go run cmd/migrate/main.go -action diff -name add_orders
|
||||
|
||||
# 校验
|
||||
go run cmd/migrate/main.go -action validate
|
||||
|
||||
# 预览
|
||||
go run cmd/migrate/main.go -action apply -dry-run
|
||||
|
||||
# 应用
|
||||
go run cmd/migrate/main.go -action apply
|
||||
|
||||
# 显式选择 Atlas 环境
|
||||
go run cmd/migrate/main.go -action status -env local_mysql
|
||||
```
|
||||
|
||||
迁移工具会根据 `app.environment` 和 `database.driver` 自动选择对应的 Atlas 环境。三种数据库的迁移文件不可混用。
|
||||
|
||||
## 接口文档
|
||||
|
||||
安装 Swag 并重新生成:
|
||||
|
||||
```bash
|
||||
go install github.com/swaggo/swag/cmd/swag@v1.8.12
|
||||
swag init
|
||||
```
|
||||
|
||||
生成文件位于 `docs/`,应用运行时不依赖 Swag CLI。
|
||||
|
||||
## 可观测性
|
||||
|
||||
- `GET /api/ping`:liveness,不访问外部服务
|
||||
- `GET /api/health`:readiness,依赖异常时返回 HTTP 503
|
||||
- `GET /metrics`:Prometheus Counter 和 Histogram
|
||||
- `X-Request-ID`:接收上游 ID 或自动生成,并写入响应和日志
|
||||
- OpenTelemetry:启用后通过 OTLP HTTP 导出 Gin 请求 Span
|
||||
|
||||
Docker Compose 默认提供 Jaeger UI:`http://localhost:16686`。
|
||||
|
||||
## 测试
|
||||
|
||||
单元测试和静态检查:
|
||||
|
||||
```bash
|
||||
go test ./...
|
||||
go test -race ./config ./database ./middlewares ./modules/ws
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
PostgreSQL 和 MySQL 集成测试:
|
||||
|
||||
```bash
|
||||
export TEST_POSTGRES_DSN='postgres://skeleton:skeleton@127.0.0.1:5432/skeleton?sslmode=disable'
|
||||
export TEST_MYSQL_DSN='skeleton:skeleton@tcp(127.0.0.1:3306)/skeleton?charset=utf8mb4&parseTime=True&loc=Local'
|
||||
go test -tags=integration ./database
|
||||
```
|
||||
|
||||
Makefile 快捷命令:
|
||||
|
||||
```bash
|
||||
make test
|
||||
make vet
|
||||
make integration
|
||||
```
|
||||
|
||||
## 编译
|
||||
|
||||
当前平台无 CGO 构建:
|
||||
|
||||
```bash
|
||||
make build
|
||||
```
|
||||
|
||||
Linux、macOS、Windows x64/amd64 交叉编译:
|
||||
|
||||
```bash
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o dist/skeleton-linux-amd64 .
|
||||
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o dist/skeleton-darwin-amd64 .
|
||||
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o dist/skeleton-windows-amd64.exe .
|
||||
```
|
||||
|
||||
项目封装命令:
|
||||
|
||||
```bash
|
||||
VERSION=0.1.0 make build-x64
|
||||
```
|
||||
|
||||
SQLite 官方驱动依赖 CGO。跨平台 `CGO_ENABLED=0` 产物支持 PostgreSQL 和 MySQL;SQLite 应在目标平台原生构建:
|
||||
|
||||
```bash
|
||||
make build-native
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
默认启动应用、PostgreSQL、Redis、Atlas 迁移和 Jaeger:
|
||||
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
额外启动 MySQL:
|
||||
|
||||
```bash
|
||||
docker compose --profile mysql up -d mysql
|
||||
```
|
||||
|
||||
停止:
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
```
|
||||
|
||||
删除本地 Compose 数据卷:
|
||||
|
||||
```bash
|
||||
docker compose down -v
|
||||
```
|
||||
|
||||
## 开发新模块
|
||||
|
||||
推荐结构:
|
||||
|
||||
```text
|
||||
modules/order/
|
||||
├── controller.go
|
||||
├── service.go
|
||||
├── types.go
|
||||
└── repository.go
|
||||
```
|
||||
|
||||
开发流程:
|
||||
|
||||
1. 在 `modules/` 添加业务代码。
|
||||
2. 在 `routes/rest/` 注册公开或 JWT 私有路由。
|
||||
3. 在 `models/` 添加或修改 GORM 模型。
|
||||
4. 为目标数据库分别生成和检查 Atlas 迁移。
|
||||
5. 添加单元测试和必要的集成测试。
|
||||
6. 更新 Swag 注解并执行 `swag init`。
|
||||
|
||||
## 安全说明
|
||||
|
||||
该仓库是脚手架,不应在未经审查的情况下直接用于生产:
|
||||
|
||||
- 必须修改默认 JWT 密钥和示例数据库密码。
|
||||
- 根据实际前端域名收紧 CORS 和 WebSocket Origin 策略。
|
||||
- 示例注册接口应增加邀请码、管理员权限或在生产环境关闭。
|
||||
- 多实例 Token 撤销必须启用 Redis。
|
||||
- 多实例 WebSocket 广播必须接入外部消息系统。
|
||||
- TLS 应由网关、Ingress 或应用部署环境终止。
|
||||
|
||||
请通过私有渠道报告安全问题,不要在公开 Issue 中提交密钥或可利用细节。
|
||||
|
||||
## 贡献
|
||||
|
||||
欢迎提交 Issue 和 Pull Request。提交前请至少执行:
|
||||
|
||||
```bash
|
||||
go fmt ./...
|
||||
go test ./...
|
||||
go vet ./...
|
||||
```
|
||||
|
||||
建议每个 Pull Request 聚焦一个主题,并同步更新测试、迁移和文档。
|
||||
|
||||
## License
|
||||
|
||||
当前仓库尚未包含许可证文件。正式公开分发前,请由项目维护者选择并添加合适的开源许可证。
|
||||
|
||||
Reference in New Issue
Block a user