Golang通用HTTP请求处理函数实现
Golang通用HTTP请求处理函数实现 以下是用于处理 HTTP 请求的通用函数
func Process[Req GoLibRequest, Resp GoLibResponse](w http.ResponseWriter, r *http.Request, processFunc func(request GoLibRequest, response *GoLibResponse) error) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
request := GoLibRequest{MsgId: GetMsgID()}
response := GoLibResponse{MsgId: GetMsgID()}
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
Logger.Errorf("Decoding body failed: %v", err)
resErr := NewHTTPError(err, 400, "Bad request : invalid JSON.", "EGN002")
response.Error = resErr
json.NewEncoder(w).Encode(response)
return
}
resErr := processFunc(request, &response)
if resErr != nil {
Logger.Errorf("Unable to process request: %v", resErr)
response.Error = resErr
w.WriteHeader(http.StatusInternalServerError)
} else {
w.WriteHeader(200)
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(response); err != nil {
log.Printf("Encoding response failed: %v", err)
}
}
}
如何正确地将此函数传递给 mux 路由器。
目前按以下方式传递
sm := http.NewServeMux()
sm.HandleFunc("/login", lib.Process(ProcessLogin))
s := &http.Server{
Addr: ":9091",
Handler: sm,
IdleTimeout: 120 * time.Second,
ReadTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
}
go func() {
err := s.ListenAndServe()
if err != nil {
lib.Logger.Error(err)
}
}()
更多关于Golang通用HTTP请求处理函数实现的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang通用HTTP请求处理函数实现的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个类型参数使用不当的问题。你的 Process 函数期望三个参数,但调用时只传递了一个 processFunc。
问题在于你的 Process 函数签名定义有误。它应该返回 http.HandlerFunc,而不是接受 w 和 r 作为参数。以下是修正后的实现:
func Process[Req GoLibRequest, Resp GoLibResponse](processFunc func(request Req, response *Resp) error) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var request Req
var response Resp
// 如果请求类型有 MsgId 字段,可以这样初始化
// 需要确保 Req 和 Resp 类型有相应的方法
if reqWithMsgID, ok := any(&request).(interface{ SetMsgID(string) }); ok {
reqWithMsgID.SetMsgID(GetMsgID())
}
if respWithMsgID, ok := any(&response).(interface{ SetMsgID(string) }); ok {
respWithMsgID.SetMsgID(GetMsgID())
}
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
Logger.Errorf("Decoding body failed: %v", err)
resErr := NewHTTPError(err, 400, "Bad request : invalid JSON.", "EGN002")
// 需要确保 Resp 类型有 Error 字段
if respWithError, ok := any(&response).(interface{ SetError(error) }); ok {
respWithError.SetError(resErr)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
json.NewEncoder(w).Encode(response)
return
}
resErr := processFunc(request, &response)
if resErr != nil {
Logger.Errorf("Unable to process request: %v", resErr)
if respWithError, ok := any(&response).(interface{ SetError(error) }); ok {
respWithError.SetError(resErr)
}
w.WriteHeader(http.StatusInternalServerError)
} else {
w.WriteHeader(200)
}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(response); err != nil {
log.Printf("Encoding response failed: %v", err)
}
}
}
然后定义你的请求和响应类型:
type LoginRequest struct {
MsgId string `json:"msg_id"`
Username string `json:"username"`
Password string `json:"password"`
}
func (r *LoginRequest) SetMsgID(id string) {
r.MsgId = id
}
type LoginResponse struct {
MsgId string `json:"msg_id"`
Token string `json:"token,omitempty"`
Error string `json:"error,omitempty"`
}
func (r *LoginResponse) SetMsgID(id string) {
r.MsgId = id
}
func (r *LoginResponse) SetError(err error) {
if err != nil {
r.Error = err.Error()
}
}
处理函数:
func ProcessLogin(request LoginRequest, response *LoginResponse) error {
// 验证逻辑
if request.Username == "admin" && request.Password == "password" {
response.Token = "generated-jwt-token"
return nil
}
return errors.New("invalid credentials")
}
路由器配置:
sm := http.NewServeMux()
sm.HandleFunc("/login", lib.Process[LoginRequest, LoginResponse](ProcessLogin))
s := &http.Server{
Addr: ":9091",
Handler: sm,
IdleTimeout: 120 * time.Second,
ReadTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
}
go func() {
err := s.ListenAndServe()
if err != nil {
lib.Logger.Error(err)
}
}()
关键修正:
Process函数现在只接受processFunc参数,返回http.HandlerFunc- 使用类型断言来安全地访问
MsgId和Error字段 - 类型参数
Req和Resp在函数签名中正确使用 - 处理函数现在可以正确传递给
HandleFunc

