golang请求响应拦截与处理插件库mediary的使用
Golang请求响应拦截与处理插件库mediary的使用
概述
mediary是一个Golang库,允许您为http.Client添加拦截器,实现以下功能:
- 将请求和/或响应转储到日志
- 在发送请求前修改请求或在返回响应前修改响应
- 使用Opentracing/Jaeger添加追踪信息
- 向statsd发送指标
- 其他功能,同时仍然使用"常规"的http.Client
基本用法
var client *http.Client
client = mediary.Init().AddInterceptors(your interceptor).Build()
client.Get("https://golang.org")
转储示例
client := mediary.Init().AddInterceptors(dumpInterceptor).Build()
client.Get("https://golang.org")
func dumpInterceptor(req *http.Request, handler mediary.Handler) (*http.Response, error) {
if bytes, err := httputil.DumpRequestOut(req, true); err == nil {
fmt.Printf("%s", bytes)
//GET / HTTP/1.1
//Host: golang.org
//User-Agent: Go-http-client/1.1
//Accept-Encoding: gzip
}
return handler(req)
}
拦截器
Interceptor是一个函数
type Interceptor func(*http.Request, Handler) (*http.Response, error)
Handler只是http.Roundtripper函数RoundTrip的别名
type Handler func(*http.Request) (*http.Response, error)
多个拦截器
可以链式添加多个拦截器
client := mediary.Init().
AddInterceptors(First Interceptor, Second Interceptor).
AddInterceptors(Third Interceptor).
Build()
拦截器的工作流程如下:
- 第一个拦截器:处理请求
- 第二个拦截器:处理请求
- 第三个拦截器:处理请求
- Handler <-- 实际的HTTP调用
- 第三个拦截器:处理响应
- 第三个拦截器:处理请求
- 第二个拦截器:处理响应
- 第二个拦截器:处理请求
- 第一个拦截器:处理响应
使用自定义客户端/传输
如果您已经有一个预配置的http.Client,也可以使用它
yourClient := &http.Client{}
yourClientWithInterceptor := mediary.Init().
WithPreconfiguredClient(yourClient).
AddInterceptors(your interceptor).
Build()
完整示例
package main
import (
"fmt"
"net/http"
"net/http/httputil"
"github.com/HereMobilityDevelopers/mediary"
)
func main() {
// 创建带拦截器的客户端
client := mediary.Init().
AddInterceptors(loggingInterceptor).
AddInterceptors(addHeaderInterceptor).
Build()
// 发送请求
resp, err := client.Get("https://golang.org")
if err != nil {
fmt.Printf("请求失败: %v\n", err)
return
}
defer resp.Body.Close()
fmt.Printf("响应状态码: %d\n", resp.StatusCode)
}
// 日志拦截器
func loggingInterceptor(req *http.Request, handler mediary.Handler) (*http.Response, error) {
// 打印请求信息
if bytes, err := httputil.DumpRequestOut(req, true); err == nil {
fmt.Printf("请求信息:\n%s\n", bytes)
}
// 继续处理请求
resp, err := handler(req)
// 打印响应信息
if resp != nil && err == nil {
fmt.Printf("响应状态码: %d\n", resp.StatusCode)
}
return resp, err
}
// 添加请求头拦截器
func addHeaderInterceptor(req *http.Request, handler mediary.Handler) (*http.Response, error) {
// 添加自定义请求头
req.Header.Add("X-Custom-Header", "mediary-example")
// 继续处理请求
return handler(req)
}
这个示例展示了如何使用mediary创建带有两个拦截器的HTTP客户端:
- loggingInterceptor - 记录请求和响应信息
- addHeaderInterceptor - 添加自定义请求头
通过mediary,您可以轻松地为HTTP客户端添加各种中间件功能,而不需要修改底层HTTP实现。
更多关于golang请求响应拦截与处理插件库mediary的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang请求响应拦截与处理插件库mediary的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang请求响应拦截与处理插件库mediary的使用
mediary是一个轻量级的Golang中间件库,专门用于HTTP请求和响应的拦截与处理。它提供了一种简单的方式来在HTTP客户端请求前后添加处理逻辑,类似于中间件模式。
基本概念
mediary的核心思想是允许你在HTTP请求发出前和收到响应后插入自定义处理逻辑,这些逻辑被称为"中间件"。每个中间件都可以修改请求或响应,或者执行其他操作如日志记录、认证等。
安装
go get github.com/HereMobilityDevelopers/mediary
基本用法
1. 创建带有中间件的HTTP客户端
package main
import (
"fmt"
"net/http"
"log"
"github.com/HereMobilityDevelopers/mediary"
)
func main() {
// 创建带有中间件的客户端
client := mediary.Init().WithDefaultClient()
// 添加请求前中间件
client.AddRequestInterceptors(func(req *http.Request) error {
fmt.Println("请求URL:", req.URL)
req.Header.Add("X-Custom-Header", "my-value")
return nil
})
// 添加响应后中间件
client.AddResponseInterceptors(func(resp *http.Response, err error) error {
if err != nil {
fmt.Println("请求出错:", err)
return err
}
fmt.Println("响应状态码:", resp.StatusCode)
return nil
})
// 使用客户端发送请求
resp, err := client.Get("https://httpbin.org/get")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
fmt.Println("最终响应状态:", resp.Status)
}
2. 链式调用
mediary支持链式调用,使代码更简洁:
client := mediary.Init().
WithDefaultClient().
AddRequestInterceptors(logRequest).
AddResponseInterceptors(logResponse)
高级用法
1. 自定义HTTP客户端
client := mediary.Init().
WithClient(&http.Client{
Timeout: 30 * time.Second,
}).
AddRequestInterceptors(authMiddleware)
2. 多个中间件
可以添加多个中间件,它们会按照添加顺序执行:
client := mediary.Init().
WithDefaultClient().
AddRequestInterceptors(logRequest).
AddRequestInterceptors(addAuthHeader).
AddResponseInterceptors(logResponse).
AddResponseInterceptors(checkStatusCode)
3. 错误处理
中间件可以返回错误,如果请求前中间件返回错误,请求将不会发送;如果响应后中间件返回错误,会传递给调用者:
client.AddRequestInterceptors(func(req *http.Request) error {
if req.URL.Host == "blocked.com" {
return fmt.Errorf("访问被阻止的域名")
}
return nil
})
实际应用示例
1. 认证中间件
func authMiddleware(req *http.Request) error {
token := getAuthToken() // 实现获取token的逻辑
req.Header.Set("Authorization", "Bearer "+token)
return nil
}
client := mediary.Init().
WithDefaultClient().
AddRequestInterceptors(authMiddleware)
2. 日志中间件
func logRequest(req *http.Request) error {
log.Printf("请求: %s %s", req.Method, req.URL)
return nil
}
func logResponse(resp *http.Response, err error) error {
if err != nil {
log.Printf("请求错误: %v", err)
return err
}
log.Printf("响应: %s %s - %d", resp.Request.Method, resp.Request.URL, resp.StatusCode)
return nil
}
client := mediary.Init().
WithDefaultClient().
AddRequestInterceptors(logRequest).
AddResponseInterceptors(logResponse)
3. 重试中间件
func retryMiddleware(resp *http.Response, err error) error {
if err != nil || resp.StatusCode >= 500 {
// 实现重试逻辑
return fmt.Errorf("需要重试")
}
return nil
}
client := mediary.Init().
WithDefaultClient().
AddResponseInterceptors(retryMiddleware)
注意事项
- 中间件的执行顺序很重要,先添加的中间件会先执行
- 请求前中间件可以修改请求,响应后中间件可以修改响应
- 如果中间件返回错误,处理链会中断
- 对于复杂的中间件链,考虑将中间件拆分为单独的函数以提高可读性
mediary是一个轻量但功能强大的库,特别适合需要对HTTP请求和响应进行统一处理的场景,如API客户端库的开发。通过中间件模式,你可以将横切关注点(如认证、日志、错误处理等)与业务逻辑分离,使代码更加清晰和可维护。