答案:Go语言中通过定义统一的错误响应结构体和错误码常量,结合工厂函数与中间件,实现REST API的标准化错误返回,提升前后端协作效率与系统可维护性。
在Go语言构建的REST API中,统一的错误返回格式有助于前端或API调用者快速理解错误原因并做相应处理。以下是一个常见的错误返回规范示例,包含结构设计、HTTP状态码使用和实际代码实现。
统一错误响应结构
定义一个通用的错误响应体结构,便于前后端达成一致。
{ "error": { "code": "invalid_request", "message": "请求参数缺失或格式错误", "details": "field 'email' is required" } }
说明:
- code:机器可读的错误码,如
invalid_request
、
not_found
- message:人类可读的错误信息(可本地化)
- details:可选字段,用于补充上下文,如校验失败字段
定义错误类型和构造函数
在Go中可以通过结构体和工厂函数来封装错误响应。
立即学习“go语言免费学习笔记(深入)”;
type ErrorResponse struct { Error struct { Code string `json:"code"` Message string `json:"message"` Details string `json:"details,omitempty"` } `json:"error"` } func NewErrorResponse(code, message, details string) *ErrorResponse { resp := ErrorResponse{} resp.Error.Code = code resp.Error.Message = message resp.Error.Details = details return &resp }
常见错误码可定义为常量:
const ( ErrInvalidRequest = "invalid_request" ErrUnauthorized = "unauthorized" ErrNotFound = "not_found" ErrInternal = "internal_error" )
在HTTP Handler中使用示例
结合
net/http
返回标准错误响应。
func GetUserHandler(w http.ResponseWriter, r *http.Request) { id := r.PathValue("id") if id == "" { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadRequest) resp := NewErrorResponse( ErrInvalidRequest, "用户ID不能为空", "path param 'id' is missing", ) json.NewEncoder(w).Encode(resp) return } // 模拟查询用户 user, err := db.GetUser(id) if err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) resp := NewErrorResponse(ErrInternal, "服务器内部错误", err.Error()) json.NewEncoder(w).Encode(resp) return } if user == nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusNotFound) resp := NewErrorResponse(ErrNotFound, "用户不存在", "user with id "+id+" not found") json.NewEncoder(w).Encode(resp) return } json.NewEncoder(w).Encode(user) } </font>
进阶:中间件统一错误处理
可以结合自定义错误类型和中间件,实现更优雅的错误处理。
type AppError struct { Code string Message string Details string Status int } func (e *AppError) Error() string { return e.Message } func ErrorMiddleware(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { defer func() { if err := recover(); err != nil { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) resp := NewErrorResponse(ErrInternal, "系统错误", fmt.Sprintf("%v", err)) json.NewEncoder(w).Encode(resp) } }() next(w, r) } }
这样可以在业务逻辑中直接返回或抛出自定义错误,在中间件中统一处理。
基本上就这些。保持错误格式一致、语义清晰,能显著提升API的可用性和维护性。
golang js 前端 json go go语言 app 后端 ai api调用 red 中间件 常量 封装 构造函数 结构体 Go语言 http