中间件

怎样自己写一个中间件?

比如有以下需求

  • 通过该中间件去统计请求数目、状态和时间。
  • 中间件把写过写回响应。

Server

server.go

  1. package main
  2. import (
  3. "net/http"
  4. "strconv"
  5. "sync"
  6. "time"
  7. "github.com/labstack/echo"
  8. )
  9. type (
  10. Stats struct {
  11. Uptime time.Time `json:"uptime"`
  12. RequestCount uint64 `json:"requestCount"`
  13. Statuses map[string]int `json:"statuses"`
  14. mutex sync.RWMutex
  15. }
  16. )
  17. func NewStats() *Stats {
  18. return &Stats{
  19. Uptime: time.Now(),
  20. Statuses: make(map[string]int),
  21. }
  22. }
  23. // Process is the middleware function.
  24. func (s *Stats) Process(next echo.HandlerFunc) echo.HandlerFunc {
  25. return func(c echo.Context) error {
  26. if err := next(c); err != nil {
  27. c.Error(err)
  28. }
  29. s.mutex.Lock()
  30. defer s.mutex.Unlock()
  31. s.RequestCount++
  32. status := strconv.Itoa(c.Response().Status)
  33. s.Statuses[status]++
  34. return nil
  35. }
  36. }
  37. // Handle is the endpoint to get stats.
  38. func (s *Stats) Handle(c echo.Context) error {
  39. s.mutex.RLock()
  40. defer s.mutex.RUnlock()
  41. return c.JSON(http.StatusOK, s)
  42. }
  43. // ServerHeader middleware adds a `Server` header to the response.
  44. func ServerHeader(next echo.HandlerFunc) echo.HandlerFunc {
  45. return func(c echo.Context) error {
  46. c.Response().Header().Set(echo.HeaderServer, "Echo/3.0")
  47. return next(c)
  48. }
  49. }
  50. func main() {
  51. e := echo.New()
  52. // Debug mode
  53. e.Debug = true
  54. //-------------------
  55. // Custom middleware
  56. //-------------------
  57. // Stats
  58. s := NewStats()
  59. e.Use(s.Process)
  60. e.GET("/stats", s.Handle) // Endpoint to get stats
  61. // Server header
  62. e.Use(ServerHeader)
  63. // Handler
  64. e.GET("/", func(c echo.Context) error {
  65. return c.String(http.StatusOK, "Hello, World!")
  66. })
  67. // Start server
  68. e.Logger.Fatal(e.Start(":1323"))
  69. }

响应

响应头

  1. Content-Length:122
  2. Content-Type:application/json; charset=utf-8
  3. Date:Thu, 14 Apr 2016 20:31:46 GMT
  4. Server:Echo/2.0

响应体

  1. {
  2. "uptime": "2016-04-14T13:28:48.486548936-07:00",
  3. "requestCount": 5,
  4. "statuses": {
  5. "200": 4,
  6. "404": 1
  7. }
  8. }