Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用gorilla mmux为所有路由应用相同的处理程序_Go_Handler_Gorilla_Mux - Fatal编程技术网

如何使用gorilla mmux为所有路由应用相同的处理程序

如何使用gorilla mmux为所有路由应用相同的处理程序,go,handler,gorilla,mux,Go,Handler,Gorilla,Mux,我正在使用一个有价值的rootHandler来处理生成的错误。我想知道如何将此处理程序用于api可能服务的每个端点 r := mux.NewRouter() r.Handle("/api/endpoint0", rootHandler(function0)).Methods("POST") r.HandleFunc("/api/endpoint1", function1).Methods("POST") r.HandleFunc("/api/endpoint2", function2).Met

我正在使用一个有价值的
rootHandler
来处理生成的错误。我想知道如何将此处理程序用于api可能服务的每个端点

r := mux.NewRouter()

r.Handle("/api/endpoint0", rootHandler(function0)).Methods("POST")
r.HandleFunc("/api/endpoint1", function1).Methods("POST")
r.HandleFunc("/api/endpoint2", function2).Methods("POST")

    s := &http.Server{
        Handler:      r,
        Addr:         "127.0.0.1:8080",
        WriteTimeout: 15 * time.Second,
        ReadTimeout:  15 * time.Second,
    }
我的错误处理程序的工作方式如下:

type rootHandler func(http.ResponseWriter, *http.Request) error

func (fn rootHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    err := fn(w, r) // Call handler function
    if err == nil {
        return
    }
    //log error or w/e
}

func NewHTTPError(err error, status int, detail string) error {
    return &HTTPError{
        Cause:  err,
        Detail: detail,
        Status: status,
    }
}
我使用的一个示例函数:

func function0(w http.ResponseWriter, r *http.Request) (err error) {
    if err = notLogged(); err != nil {
        return NewHTTPError(err, 400, "not authorized")
    }

}

我是否必须使用roothandle(functionName)包装每个路由函数,或者是否有方法将其应用于每个路由?

根据
rootHandler
的确切结构,您可以将其设置为中间件:

func GetRootHandlerMW(authUser SomeType) func(http.Handler) http.Handler {
  return func(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do what needs to be done?
        next.ServeHTTP(w, r)
    })
  }
}

...
r.Use(GetRootHandlerMW(authUser))
一个简单的日志中间件如下所示:

func LogMW(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        logRequest(...)
        next.ServeHTTP(w, r)
    })
}

...
r.Use(LogMW)
type RequestError struct {
   Err error
}

type requestErrorKeyType int
const requestErrorKey requestErrorKeyType=iota

func SetRequestError(req *http.Request, err error) {
   if r:=req.Context().Value(requestErrorKey); r!=nil {
       r.(*RequestError).Err=err
   }
}

// In the handler...
requestError:=RequestError{}
newReq:=request.WithContext(request.Context().WithValue(requestErrorKey,&requestError))
next.ServeHTTP(w,newReq)
if requestError.Err!=nil {
  ...
}
从添加的代码来看,您似乎希望更改HTTP处理程序函数以返回错误。这会更改函数的签名,并且不能将其用作处理程序。您可以:

  • 使用上下文将错误传递回中间件。也就是说,在处理程序的请求上下文中设置一些错误值,以便记录器中间件可以在处理程序返回后记录它,或者
  • 用错误记录器包装每个处理程序,就像您现在所做的那样
向上下文添加值将创建一个新的上下文,因此,如果使用上下文从处理程序传回值,则必须首先设置占位符。大概是这样的:

func LogMW(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        logRequest(...)
        next.ServeHTTP(w, r)
    })
}

...
r.Use(LogMW)
type RequestError struct {
   Err error
}

type requestErrorKeyType int
const requestErrorKey requestErrorKeyType=iota

func SetRequestError(req *http.Request, err error) {
   if r:=req.Context().Value(requestErrorKey); r!=nil {
       r.(*RequestError).Err=err
   }
}

// In the handler...
requestError:=RequestError{}
newReq:=request.WithContext(request.Context().WithValue(requestErrorKey,&requestError))
next.ServeHTTP(w,newReq)
if requestError.Err!=nil {
  ...
}

根据
rootHandler
的确切结构,您可以将其设置为中间件:

func GetRootHandlerMW(authUser SomeType) func(http.Handler) http.Handler {
  return func(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do what needs to be done?
        next.ServeHTTP(w, r)
    })
  }
}

...
r.Use(GetRootHandlerMW(authUser))
一个简单的日志中间件如下所示:

func LogMW(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        logRequest(...)
        next.ServeHTTP(w, r)
    })
}

...
r.Use(LogMW)
type RequestError struct {
   Err error
}

type requestErrorKeyType int
const requestErrorKey requestErrorKeyType=iota

func SetRequestError(req *http.Request, err error) {
   if r:=req.Context().Value(requestErrorKey); r!=nil {
       r.(*RequestError).Err=err
   }
}

// In the handler...
requestError:=RequestError{}
newReq:=request.WithContext(request.Context().WithValue(requestErrorKey,&requestError))
next.ServeHTTP(w,newReq)
if requestError.Err!=nil {
  ...
}
从添加的代码来看,您似乎希望更改HTTP处理程序函数以返回错误。这会更改函数的签名,并且不能将其用作处理程序。您可以:

  • 使用上下文将错误传递回中间件。也就是说,在处理程序的请求上下文中设置一些错误值,以便记录器中间件可以在处理程序返回后记录它,或者
  • 用错误记录器包装每个处理程序,就像您现在所做的那样
向上下文添加值将创建一个新的上下文,因此,如果使用上下文从处理程序传回值,则必须首先设置占位符。大概是这样的:

func LogMW(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        logRequest(...)
        next.ServeHTTP(w, r)
    })
}

...
r.Use(LogMW)
type RequestError struct {
   Err error
}

type requestErrorKeyType int
const requestErrorKey requestErrorKeyType=iota

func SetRequestError(req *http.Request, err error) {
   if r:=req.Context().Value(requestErrorKey); r!=nil {
       r.(*RequestError).Err=err
   }
}

// In the handler...
requestError:=RequestError{}
newReq:=request.WithContext(request.Context().WithValue(requestErrorKey,&requestError))
next.ServeHTTP(w,newReq)
if requestError.Err!=nil {
  ...
}

谢谢你的回复,我添加了额外的上下文,因为我的函数名有误导性。我没有尝试使用特定的authUser作为中间件,我只是想以特定的方式记录错误。不过,我将尝试研究中间件。谢谢,我想从前面提到的选项中探索第一个选项。你指的是什么?如果是这样,我将如何在http处理程序函数中继续在其上下文中添加错误?感谢您的回复,我添加了额外的上下文,因为我的函数名具有误导性。我没有尝试使用特定的authUser作为中间件,我只是想以特定的方式记录错误。不过,我将尝试研究中间件。谢谢,我想从前面提到的选项中探索第一个选项。你指的是什么?如果是这样,我将如何在http处理程序函数中继续在其上下文中添加错误?