go简单中间件的实现
2022-02-24 本文已影响0人
wilsonLwx
接之前的go + graphql的简单实现篇,虽然实现了请求,但是看不到任何请求日志,所以我就想如何实现简单的请求日志的output,首先想到的就是中间件,于是便又学习了go中间件的简单用法。
// 定义日志response的状态码和状态内容结构体
type LoggerResponseWriter struct {
http.ResponseWriter
statusCode int
statusText string
}
// 结构体LoggerResponseWriter实现http.ResponseWriter接口的WriteHeader方法
// 获取请求体的状态码和状态类容,并重新调用lw.ResponseWriter.WriteHeader重新封装
func (lw *LoggerResponseWriter) WriteHeader(code int) {
lw.statusCode = code
lw.statusText = http.StatusText(code)
lw.ResponseWriter.WriteHeader(code)
}
func NewLoggerResponseWriter(w http.ResponseWriter) *LoggerResponseWriter{
return &LoggerResponseWriter{w, http.StatusOK, http.StatusText(http.StatusOK)}
}
type NewHandler struct {
handler http.Handler
}
// NewHandler实现http.Handler的ServeHTTP方法,重新封装请求,并输出日志信息
func (l *NewHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
start := time.Now()
lw := NewLoggerResponseWriter(w)
l.handler.ServeHTTP(lw, r)
log.Printf("\"%s %s %s\" %v %d %d", r.Method, r.URL.Path, r.Proto, time.Since(start), lw.statusCode, r.ContentLength)
}
//Logger返回NewHandler实例
func Logger(h http.Handler) *NewHandler {
return &NewHandler{h}
}
如下,你可以选则使用mux封装你的handler,也可以直接使用http.Handle去处理你的handler。
// 用graphql-go/handler中间件处理graphql的http请求
h := handler.New(&handler.Config{
Schema: &schema,
Pretty: true,
GraphiQL: true,
})
http.Handle("/graphql", Logger(h))
http.ListenAndServe(":9090", nil)
// mux := http.NewServeMux()
// mux.Handle("/graphql", h)
// wrappedMux := NewLogger(mux)
// log.Fatal(http.ListenAndServe(":9090", wrappedMux))