Files
xlgo-core/response/mode.go
T
杭州明婳科技 0c9f256dfc feat(v1.1.0): HA & Manager 化
对应体检报告 #10-#24,一次性完成 v1.1.0 全部 13 项:

- #10 storage/cache/redis/jwt/logger 五组件 Manager 化(XxxManager + DefaultXxx + SetDefaultXxxManager,包级 facade 保留兼容)
- #11 删除 wire 包 + 清理 StartServerWithPort/GracefulShutdown 双轨
- #12 Lifecycle Hooks(OnInit/OnStart/OnReady/OnStop)
- #13 Server 参数配置化(timeout/TLS/unix_socket/response_mode)
- #14 JWTConfig.Expire 改 time.Duration + 删 AppConfig.TokenExpire
- #15 response Mode 开关(ModeBusiness/ModeREST)
- #16 Config.Validate 启动期校验
- #17 livez/readyz 探针路由
- #18 Prometheus metrics 中间件 + /metrics
- #19 请求级 Timeout 中间件
- #21 主库探活 + replica 健康剔除
- #22 App.Go + in-flight goroutine 管理
- #24 RequestID 默认装入 + #23 核对

Breaking:删 wire、删 TokenExpire、JWTConfig.Expire 类型变更、删双轨函数。
详见 CHANGELOG 升级说明。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 10:41:05 +08:00

87 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package response
import (
"net/http"
"sync/atomic"
"github.com/gin-gonic/gin"
)
// Mode 响应模式
type Mode int32
const (
// ModeBusiness 业务码模式(默认):所有响应 HTTP 200,错误信息通过 body 中的 code 表达。
// 兼容存量"业务码 in body"玩法。
ModeBusiness Mode = iota
// ModeREST REST 模式:失败响应按业务码映射对应的 HTTP status401/404/500...),
// body 仍带业务码。便于 APM / Prometheus / 网关 / Sentry 按 status 区分异常。
ModeREST
)
// currentMode 当前响应模式,默认 ModeBusiness。原子读写,可在运行时切换。
var currentMode atomic.Int32
// SetMode 设置全局响应模式。
func SetMode(m Mode) { currentMode.Store(int32(m)) }
// GetMode 返回当前响应模式。
func GetMode() Mode { return Mode(currentMode.Load()) }
// statusForCode 按业务码推断 HTTP status(用于 ModeREST)。
// 已知框架错误码显式映射;用户/文件/数据模块的业务错误码(1xxxx~3xxxx
// 属业务语义而非 HTTP 错误,保持 200;操作失败类(4xxxx)映射 400。
func statusForCode(code int) int {
switch code {
case CodeSuccess:
return http.StatusOK
case CodeUnauthorized, CodeTokenExpired, CodeTokenInvalid:
return http.StatusUnauthorized
case CodeForbidden:
return http.StatusForbidden
case CodeNotFound, CodeUserNotFound, CodeFileNotFound, CodeDataNotFound:
return http.StatusNotFound
case CodeDataConflict:
return http.StatusConflict
case CodeRateLimit:
return http.StatusTooManyRequests
case CodeServerError:
return http.StatusInternalServerError
case CodeServiceUnavailable:
return http.StatusServiceUnavailable
}
if code >= 40000 && code < 50000 {
return http.StatusBadRequest
}
return http.StatusOK
}
// httpStatusFor 返回当前模式下失败响应对应的 HTTP status。
func httpStatusFor(code int) int {
if GetMode() == ModeREST {
return statusForCode(code)
}
return http.StatusOK
}
// writeResp 统一写入响应,按当前 Mode 决定 HTTP status。
func writeResp(c *gin.Context, code int, msg string, data any) {
c.JSON(httpStatusFor(code), Response{
Code: code,
Msg: msg,
Data: data,
RequestID: getRequestID(c),
})
}
// Custom 显式指定 HTTP status 与业务码的响应,不受 Mode 影响。
// 适用于需要精确控制 HTTP status 的场景(如 REST 模式下的特殊端点)。
func Custom(c *gin.Context, httpStatus, code int, msg string, data any) {
c.JSON(httpStatus, Response{
Code: code,
Msg: msg,
Data: data,
RequestID: getRequestID(c),
})
}