[TOC]

原始请求转换成context.Handler

1.面向中间件 negroni-like

目录结构

主目录negroniLike

    —— main.go

代码示例

main.go

package mainimport (    "net/http"    "github.com/kataras/iris")func main() {    app := iris.New()    //FromStd将原生http.Handler,http.HandlerFunc和func(w,r,next)转换为context.Handler    irisMiddleware := iris.FromStd(negronilikeTestMiddleware)    app.Use(irisMiddleware)    // 请求 GET: http://localhost:8080/    app.Get("/", func(ctx iris.Context) {        ctx.HTML("<h1> Home </h1>")        //这会打印错误        //这个路由的处理程序永远不会被执行,因为中间件的标准没有通过    })    // 请求 GET: http://localhost:8080/ok    app.Get("/ok", func(ctx iris.Context) {        ctx.Writef("Hello world!")        // 这将打印"OK. Hello world!"    })    // http://localhost:8080    // http://localhost:8080/ok    app.Run(iris.Addr(":8080"))}func negronilikeTestMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {    if r.URL.Path == "/ok" && r.Method == "GET" {        w.Write([]byte("OK. "))        next(w, r) // 中间件        return    }    //否则打印错误    w.WriteHeader(iris.StatusBadRequest)    w.Write([]byte("Bad request"))}//如果要使用自定义上下文转换自定义处理程序,请查看routing/custom-context//一个context.Handler

negroni是go实现中间件的一种使用很广泛的模式

2.面向net/Http

目录结构

主目录nethttp

    —— main.go

代码示例

main.go

package mainimport (    "net/http"    "github.com/kataras/iris")func main() {    app := iris.New()    //FromStd将原生http.Handler,http.HandlerFunc和func(w,r,next)转换为context.Handler    irisMiddleware := iris.FromStd(nativeTestMiddleware)    app.Use(irisMiddleware)    // 请求 GET: http://localhost:8080/    app.Get("/", func(ctx iris.Context) {        ctx.HTML("Home")    })    // 请求 GET: http://localhost:8080/ok    app.Get("/ok", func(ctx iris.Context) {        ctx.HTML("<b>Hello world!</b>")    })    // http://localhost:8080    // http://localhost:8080/ok    app.Run(iris.Addr(":8080"))}func nativeTestMiddleware(w http.ResponseWriter, r *http.Request) {    println("Request path: " + r.URL.Path)}//如果要使用自定义上下文转换自定义处理程序,请查看routing/custom-context//一个context.Handler。

直接把原生的net/http满足请求接口的函数转化成中间件

3.错误中间件(raven)客户端 https://sentry.io/welcome/

1.修饰路由类型

目录结构

主目录realUsecaseRaven

    —— main.go

代码示例

main.go

package mainimport (    "errors"    "fmt"    "net/http"    "runtime/debug"    "github.com/kataras/iris"    "github.com/getsentry/raven-go")// https://docs.sentry.io/clients/go/integrations/http/func init() {    raven.SetDSN("https://<key>:<secret>@sentry.io/<project>")}func main() {    app := iris.New()    app.Get("/", func(ctx iris.Context) {        ctx.Writef("Hi")    })    // WrapRouter的示例已在此处:    // https://github.com/kataras/iris/blob/master/_examples/routing/custom-wrapper/main.go#L53    app.WrapRouter(func(w http.ResponseWriter, r *http.Request, irisRouter http.HandlerFunc) {        //完全相同的源代码:        // https://github.com/getsentry/raven-go/blob/379f8d0a68ca237cf8893a1cdfd4f574125e2c51/http.go#L70        defer func() {            if rval := recover(); rval != nil {                debug.PrintStack()                rvalStr := fmt.Sprint(rval)                packet := raven.NewPacket(rvalStr, raven.NewException(errors.New(rvalStr), raven.NewStacktrace(2, 3, nil)), raven.NewHttp(r))                raven.Capture(packet, nil)                w.WriteHeader(http.StatusInternalServerError)            }        }()        irisRouter(w, r)    })    app.Run(iris.Addr(":8080"))}

2.直接中间件类型

目录结构

主目录writingMiddleware

    —— main.go

代码示例

main.go

package mainimport (    "errors"    "fmt"    "runtime/debug"    "github.com/kataras/iris"    "github.com/getsentry/raven-go")//raven实现了Sentry错误日志记录服务的客户端。//在此示例中,您将看到如何转换任何net/http中间件//具有`(HandlerFunc)HandlerFunc`的形式。//如果`raven.RecoveryHandler`的形式是//`(http.HandlerFunc)`或`(http.HandlerFunc,下一个http.HandlerFunc)`//你可以使用`irisMiddleware:= iris.FromStd(nativeHandler)`//但它没有,但是你已经知道Iris可以直接使用net/http//因为`ctx.ResponseWriter()`和`ctx.Request()`是原来的// http.ResponseWriter和* http.Request。//(这个是一个很大的优势,因此你可以永远使用Iris :))。//本机中间件的源代码根本不会改变。// https://github.com/getsentry/raven-go/blob/379f8d0a68ca237cf8893a1cdfd4f574125e2c51/http.go#L70//唯一的补充是第18行和第39行(而不是handler(w,r))//你有一个新的Iris中间件准备使用!func irisRavenMiddleware(ctx iris.Context) {    w, r := ctx.ResponseWriter(), ctx.Request()    defer func() {        if rval := recover(); rval != nil {            debug.PrintStack()            rvalStr := fmt.Sprint(rval)            packet := raven.NewPacket(rvalStr, raven.NewException(errors.New(rvalStr), raven.NewStacktrace(2, 3, nil)), raven.NewHttp(r))            raven.Capture(packet, nil)            w.WriteHeader(iris.StatusInternalServerError)        }    }()    ctx.Next()}// https://docs.sentry.io/clients/go/integrations/http/func init() {    raven.SetDSN("https://<key>:<secret>@sentry.io/<project>")}func main() {    app := iris.New()    app.Use(irisRavenMiddleware)    app.Get("/", func(ctx iris.Context) {        ctx.Writef("Hi")    })    app.Run(iris.Addr(":8080"))}

提示

  • 主要介绍如何将原始请求转换成context.Handler
  • Negroni是面向web中间件的一种惯用方法.它是微小的,非侵入性的,并且鼓励使用net/http处理器
  • 错误中间件(raven)客户端为我们提供了一个非常清晰的报表,展示我们的响应并提高质量.这是完整的堆栈跟踪.这是一个非常强大的东西