golang实现HTTP中间件功能插件库mid的使用

Golang实现HTTP中间件功能插件库mid的使用

介绍

mid是一个用于HTTP服务的实用中间件集合,提供了多种便捷的中间件功能,可以帮助简化HTTP服务的开发。

Err中间件

Err函数将func(http.ResponseWriter, *http.Request) error转换为http.Handler,允许处理函数以更自然的方式返回错误。这些错误会导致处理程序产生HTTP 500状态码,但CodeErrResponder允许你控制此行为。

func main() {
  http.Handle("/foo", Err(fooHandler))
  http.ListenAndServe(":8080", nil)
}

func fooHandler(w http.ResponseWriter, req *http.Request) error {
  if x := req.FormValue("x"); x != "secret password" {
    return CodeErr{C: http.StatusUnauthorized}
  }
  fmt.Fprintf(w, "You know the secret password")
  return nil
}

JSON中间件

JSON函数将func(context.Context, X) (Y, error)转换为http.Handler,其中X是HTTP请求体自动JSON解码的参数类型,Y是自动JSON编码为HTTP响应的结果类型。

func main() {
  // 将请求体解析为JSON编码的字符串数组,
  // 然后排序,重新编码并返回该数组
  http.Handle("/bar", JSON(barHandler))

  http.ListenAndServe(":8080", nil)
}

func barHandler(inp []string) []string {
  sort.Strings(inp)
  return inp
}

CodeErr和Responder

CodeErr是一个error类型,适用于从ErrJSON包装的处理程序返回,可以控制返回的HTTP状态码。它包含一个HTTP状态码字段和一个嵌套的error

Responder是一个接口(由CodeErr实现),允许错误类型控制ErrJSON包装的处理程序如何响应待处理的请求。

ResponseWrapper

ResponseWrapper是一个http.ResponseWriter,它包装了一个嵌套的http.ResponseWriter,并记录了响应中发送的状态码和字节数。

Trace中间件

Trace函数包装一个http.Handler,并用请求头中找到的任何"trace ID"字符串装饰其*http.Request中的context.Context

Log中间件

Log函数包装一个http.Handler,并在进入和退出处理程序时写入一个简单的日志行。日志行包括在请求的context.Context中找到的任何"trace ID"。

以上是mid库的主要功能和使用方法,通过这些中间件可以大大简化HTTP服务的开发工作。


更多关于golang实现HTTP中间件功能插件库mid的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现HTTP中间件功能插件库mid的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang HTTP中间件功能插件库mid的使用指南

在Go语言中,HTTP中间件是一种非常强大的模式,它允许我们在请求处理链中插入额外的逻辑。下面我将介绍如何使用一个名为mid的中间件库(假设这是一个类似功能的库,因为标准库中没有直接叫mid的中间件库),以及如何实现类似的中间件功能。

基本概念

HTTP中间件是一个函数,它接收一个http.Handler并返回一个新的http.Handler,可以在调用原始处理器前后执行额外操作。

使用示例

1. 安装mid库

go get github.com/yourusername/mid

2. 基本使用

package main

import (
	"fmt"
	"net/http"
	"github.com/yourusername/mid"
)

func main() {
	// 创建一个基本处理器
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello, World!")
	})

	// 使用mid库添加中间件
	chain := mid.New(
		mid.Logger(),       // 日志记录
		mid.Recovery(),     // 错误恢复
		mid.CORS(),         // 跨域支持
		mid.Timeout(10),    // 10秒超时
	)

	// 应用中间件链
	http.Handle("/", chain.Then(handler))

	// 启动服务器
	http.ListenAndServe(":8080", nil)
}

3. 自定义中间件

func AuthMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		token := r.Header.Get("Authorization")
		if token != "valid-token" {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func main() {
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Protected Resource")
	})

	chain := mid.New(
		mid.Logger(),
		AuthMiddleware,
	)

	http.Handle("/protected", chain.Then(handler))
	http.ListenAndServe(":8080", nil)
}

4. 中间件执行顺序

func main() {
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Main Handler")
	})

	chain := mid.New(
		func(next http.Handler) http.Handler {
			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				fmt.Println("Middleware 1 - Before")
				next.ServeHTTP(w, r)
				fmt.Println("Middleware 1 - After")
			}
		},
		func(next http.Handler) http.Handler {
			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				fmt.Println("Middleware 2 - Before")
				next.ServeHTTP(w, r)
				fmt.Println("Middleware 2 - After")
			}
		},
	)

	http.Handle("/", chain.Then(handler))
	http.ListenAndServe(":8080", nil)
}

执行顺序将是:

  1. Middleware 1 - Before
  2. Middleware 2 - Before
  3. Main Handler
  4. Middleware 2 - After
  5. Middleware 1 - After

5. 常用内置中间件

func main() {
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintln(w, "Hello with various middlewares")
	})

	chain := mid.New(
		mid.Logger(),               // 记录请求日志
		mid.Recovery(),             // 捕获panic并返回500错误
		mid.Compress(),             // 响应压缩
		mid.RequestID(),            // 为每个请求添加唯一ID
		mid.RateLimit(100, time.Minute), // 每分钟100次请求限制
		mid.CORS(mid.CORSOptions{   // 跨域配置
			AllowedOrigins: []string{"*"},
			AllowedMethods: []string{"GET", "POST"},
		}),
	)

	http.Handle("/", chain.Then(handler))
	http.ListenAndServe(":8080", nil)
}

实现原理

如果你需要自己实现类似的中间件功能,可以这样做:

type Middleware func(http.Handler) http.Handler

type Chain struct {
	middlewares []Middleware
}

func New(middlewares ...Middleware) *Chain {
	return &Chain{middlewares: middlewares}
}

func (c *Chain) Then(h http.Handler) http.Handler {
	for i := len(c.middlewares) - 1; i >= 0; i-- {
		h = c.middlewares[i](h)
	}
	return h
}

总结

使用中间件可以让你:

  1. 保持处理器的简洁
  2. 复用通用逻辑
  3. 灵活组合功能
  4. 方便地添加或移除功能

在实际项目中,合理使用中间件可以大大提高代码的可维护性和可扩展性。

回到顶部