原始请求转换成context.Handler

    代码示例

    main.go

    1. package main
    2. import (
    3. "net/http"
    4. "github.com/kataras/iris"
    5. )
    6. func main() {
    7. app := iris.New()
    8. //FromStd将原生http.Handler,http.HandlerFunc和func(w,r,next)转换为context.Handler
    9. irisMiddleware := iris.FromStd(negronilikeTestMiddleware)
    10. app.Use(irisMiddleware)
    11. // 请求 GET: http://localhost:8080/
    12. app.Get("/", func(ctx iris.Context) {
    13. ctx.HTML("<h1> Home </h1>")
    14. //这会打印错误
    15. //这个路由的处理程序永远不会被执行,因为中间件的标准没有通过
    16. })
    17. // 请求 GET: http://localhost:8080/ok
    18. app.Get("/ok", func(ctx iris.Context) {
    19. ctx.Writef("Hello world!")
    20. // 这将打印"OK. Hello world!"
    21. })
    22. // http://localhost:8080
    23. // http://localhost:8080/ok
    24. app.Run(iris.Addr(":8080"))
    25. }
    26. func negronilikeTestMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
    27. if r.URL.Path == "/ok" && r.Method == "GET" {
    28. w.Write([]byte("OK. "))
    29. next(w, r) // 中间件
    30. return
    31. }
    32. //否则打印错误
    33. w.WriteHeader(iris.StatusBadRequest)
    34. w.Write([]byte("Bad request"))
    35. }
    36. //如果要使用自定义上下文转换自定义处理程序,请查看routing/custom-context
    37. //一个context.Handler

    negronigo实现中间件的一种使用很广泛的模式

    代码示例

    main.go

    1. package main
    2. import (
    3. "net/http"
    4. )
    5. func main() {
    6. app := iris.New()
    7. //FromStd将原生http.Handler,http.HandlerFunc和func(w,r,next)转换为context.Handler
    8. irisMiddleware := iris.FromStd(nativeTestMiddleware)
    9. app.Use(irisMiddleware)
    10. app.Get("/", func(ctx iris.Context) {
    11. ctx.HTML("Home")
    12. })
    13. // 请求 GET: http://localhost:8080/ok
    14. app.Get("/ok", func(ctx iris.Context) {
    15. ctx.HTML("<b>Hello world!</b>")
    16. })
    17. // http://localhost:8080
    18. // http://localhost:8080/ok
    19. app.Run(iris.Addr(":8080"))
    20. }
    21. func nativeTestMiddleware(w http.ResponseWriter, r *http.Request) {
    22. println("Request path: " + r.URL.Path)
    23. }
    24. //如果要使用自定义上下文转换自定义处理程序,请查看routing/custom-context
    25. //一个context.Handler。

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

    目录结构

    代码示例

    main.go

    1. package main
    2. import (
    3. "errors"
    4. "fmt"
    5. "net/http"
    6. "runtime/debug"
    7. "github.com/kataras/iris"
    8. "github.com/getsentry/raven-go"
    9. )
    10. // https://docs.sentry.io/clients/go/integrations/http/
    11. func init() {
    12. raven.SetDSN("https://<key>:<secret>@sentry.io/<project>")
    13. }
    14. func main() {
    15. app := iris.New()
    16. app.Get("/", func(ctx iris.Context) {
    17. ctx.Writef("Hi")
    18. })
    19. // WrapRouter的示例已在此处:
    20. // https://github.com/kataras/iris/blob/master/_examples/routing/custom-wrapper/main.go#L53
    21. app.WrapRouter(func(w http.ResponseWriter, r *http.Request, irisRouter http.HandlerFunc) {
    22. //完全相同的源代码:
    23. // https://github.com/getsentry/raven-go/blob/379f8d0a68ca237cf8893a1cdfd4f574125e2c51/http.go#L70
    24. defer func() {
    25. if rval := recover(); rval != nil {
    26. debug.PrintStack()
    27. rvalStr := fmt.Sprint(rval)
    28. packet := raven.NewPacket(rvalStr, raven.NewException(errors.New(rvalStr), raven.NewStacktrace(2, 3, nil)), raven.NewHttp(r))
    29. raven.Capture(packet, nil)
    30. w.WriteHeader(http.StatusInternalServerError)
    31. }()
    32. irisRouter(w, r)
    33. })
    34. }

    2.直接中间件类型

    目录结构

    主目录writingMiddleware

    代码示例

    1. package main
    2. import (
    3. "errors"
    4. "fmt"
    5. "runtime/debug"
    6. "github.com/kataras/iris"
    7. "github.com/getsentry/raven-go"
    8. )
    9. //raven实现了Sentry错误日志记录服务的客户端。
    10. //在此示例中,您将看到如何转换任何net/http中间件
    11. //具有`(HandlerFunc)HandlerFunc`的形式。
    12. //如果`raven.RecoveryHandler`的形式是
    13. //`(http.HandlerFunc)`或`(http.HandlerFunc,下一个http.HandlerFunc)`
    14. //你可以使用`irisMiddleware:= iris.FromStd(nativeHandler)`
    15. //但它没有,但是你已经知道Iris可以直接使用net/http
    16. //因为`ctx.ResponseWriter()`和`ctx.Request()`是原来的
    17. // http.ResponseWriter和* http.Request。
    18. //(这个是一个很大的优势,因此你可以永远使用Iris :))。
    19. //本机中间件的源代码根本不会改变。
    20. // https://github.com/getsentry/raven-go/blob/379f8d0a68ca237cf8893a1cdfd4f574125e2c51/http.go#L70
    21. //唯一的补充是第18行和第39行(而不是handler(w,r))
    22. //你有一个新的Iris中间件准备使用!
    23. func irisRavenMiddleware(ctx iris.Context) {
    24. w, r := ctx.ResponseWriter(), ctx.Request()
    25. defer func() {
    26. if rval := recover(); rval != nil {
    27. debug.PrintStack()
    28. rvalStr := fmt.Sprint(rval)
    29. packet := raven.NewPacket(rvalStr, raven.NewException(errors.New(rvalStr), raven.NewStacktrace(2, 3, nil)), raven.NewHttp(r))
    30. raven.Capture(packet, nil)
    31. w.WriteHeader(iris.StatusInternalServerError)
    32. }
    33. }()
    34. ctx.Next()
    35. }
    36. // https://docs.sentry.io/clients/go/integrations/http/
    37. func init() {
    38. raven.SetDSN("https://<key>:<secret>@sentry.io/<project>")
    39. }
    40. func main() {
    41. app := iris.New()
    42. app.Use(irisRavenMiddleware)
    43. app.Get("/", func(ctx iris.Context) {
    44. ctx.Writef("Hi")
    45. })
    46. app.Run(iris.Addr(":8080"))
    47. }
    • 主要介绍如何将原始请求转换成context.Handler
    • Negroni是面向web中间件的一种惯用方法.它是微小的,非侵入性的,并且鼓励使用net/http处理器
    • 错误中间件(raven)客户端为我们提供了一个非常清晰的报表,展示我们的响应并提高质量.这是完整的堆栈跟踪.这是一个非常强大的东西