167 lines
4.1 KiB
Go
167 lines
4.1 KiB
Go
package main
|
||
|
||
import (
|
||
"context"
|
||
"log"
|
||
"net/http"
|
||
"time"
|
||
|
||
"git.toowon.com/jimmy/go-common/factory"
|
||
)
|
||
|
||
// 示例:Factory黑盒模式 - 最简化的使用方式
|
||
//
|
||
// 核心理念:
|
||
//
|
||
// 外部项目只需要传递一个配置文件路径,
|
||
// 直接使用 factory 的黑盒方法,无需获取内部对象
|
||
func main() {
|
||
// ====== 第1步:创建工厂(只需要配置文件路径)======
|
||
fac, err := factory.NewFactoryFromFile("config.json")
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
|
||
// ====== 第2步:使用黑盒方法(推荐)======
|
||
|
||
// 1. 获取中间件链(自动配置所有基础中间件)
|
||
chain := fac.GetMiddlewareChain()
|
||
|
||
// 2. 添加项目特定的自定义中间件
|
||
chain.Append(authMiddleware, metricsMiddleware)
|
||
|
||
// 3. 注册路由
|
||
http.Handle("/api/users", chain.ThenFunc(handleUsers))
|
||
http.Handle("/api/upload", chain.ThenFunc(handleUpload))
|
||
|
||
// 4. 启动服务
|
||
log.Println("Server started on :8080")
|
||
log.Fatal(http.ListenAndServe(":8080", nil))
|
||
}
|
||
|
||
// ====== API处理器 ======
|
||
|
||
// 用户列表
|
||
func handleUsers(w http.ResponseWriter, r *http.Request) {
|
||
// 创建工厂(在处理器中也可以复用)
|
||
fac, _ := factory.NewFactoryFromFile("config.json")
|
||
ctx := context.Background()
|
||
|
||
// 1. 使用数据库(需要获取对象,因为GORM很复杂)
|
||
db, _ := fac.GetDatabase()
|
||
var users []map[string]interface{}
|
||
db.Table("users").Find(&users)
|
||
|
||
// 2. 使用Redis(黑盒方法,推荐)
|
||
cacheKey := "users:list"
|
||
cached, _ := fac.RedisGet(ctx, cacheKey)
|
||
if cached != "" {
|
||
fac.Success(w, cached)
|
||
return
|
||
}
|
||
|
||
// 3. 记录日志(黑盒方法,推荐)
|
||
fac.LogInfof(map[string]interface{}{
|
||
"action": "list_users",
|
||
"count": len(users),
|
||
}, "查询用户列表")
|
||
|
||
// 4. 缓存结果
|
||
fac.RedisSet(ctx, cacheKey, users, 5*time.Minute)
|
||
|
||
fac.Success(w, users)
|
||
}
|
||
|
||
// 文件上传
|
||
func handleUpload(w http.ResponseWriter, r *http.Request) {
|
||
fac, _ := factory.NewFactoryFromFile("config.json")
|
||
ctx := context.Background()
|
||
|
||
// 解析上传的文件
|
||
file, header, err := r.FormFile("file")
|
||
if err != nil {
|
||
fac.LogError("文件上传失败: %v", err)
|
||
fac.Error(w, 400, "文件上传失败")
|
||
return
|
||
}
|
||
defer file.Close()
|
||
|
||
// 上传文件(黑盒方法,自动选择OSS或MinIO)
|
||
objectKey := "uploads/" + header.Filename
|
||
url, err := fac.UploadFile(ctx, objectKey, file, header.Header.Get("Content-Type"))
|
||
if err != nil {
|
||
fac.LogError("文件上传到存储失败: %v", err)
|
||
fac.Error(w, 500, "文件上传失败")
|
||
return
|
||
}
|
||
|
||
// 记录上传日志
|
||
fac.LogInfof(map[string]interface{}{
|
||
"filename": header.Filename,
|
||
"size": header.Size,
|
||
"url": url,
|
||
}, "文件上传成功")
|
||
|
||
fac.Success(w, map[string]interface{}{
|
||
"url": url,
|
||
})
|
||
}
|
||
|
||
// ====== 自定义中间件 ======
|
||
|
||
// 认证中间件
|
||
func authMiddleware(next http.Handler) http.Handler {
|
||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
fac, _ := factory.NewFactoryFromFile("config.json")
|
||
ctx := context.Background()
|
||
|
||
// 获取token
|
||
token := r.Header.Get("Authorization")
|
||
if token == "" {
|
||
fac.Error(w, 401, "未授权")
|
||
return
|
||
}
|
||
|
||
// 从Redis验证token(黑盒方法)
|
||
userID, err := fac.RedisGet(ctx, "token:"+token)
|
||
if err != nil || userID == "" {
|
||
fac.Error(w, 401, "token无效")
|
||
return
|
||
}
|
||
|
||
// 记录日志(黑盒方法)
|
||
fac.LogInfof(map[string]interface{}{
|
||
"user_id": userID,
|
||
"path": r.URL.Path,
|
||
}, "用户请求")
|
||
|
||
// 将用户ID存入context(或header)
|
||
r.Header.Set("X-User-ID", userID)
|
||
next.ServeHTTP(w, r)
|
||
})
|
||
}
|
||
|
||
// 指标中间件
|
||
func metricsMiddleware(next http.Handler) http.Handler {
|
||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
fac, _ := factory.NewFactoryFromFile("config.json")
|
||
ctx := context.Background()
|
||
|
||
start := time.Now()
|
||
|
||
// 继续处理请求
|
||
next.ServeHTTP(w, r)
|
||
|
||
// 记录请求耗时到Redis(黑盒方法)
|
||
latency := time.Since(start).Milliseconds()
|
||
key := "metrics:" + r.URL.Path
|
||
fac.RedisSet(ctx, key, latency, time.Minute)
|
||
|
||
// 记录指标日志(黑盒方法)
|
||
fac.LogDebugf(map[string]interface{}{
|
||
"path": r.URL.Path,
|
||
"latency": latency,
|
||
}, "请求指标")
|
||
})
|
||
}
|