详解Golang net/http包中的RoundTripper接口

 更新时间:2023年09月22日 10:02:44   作者:路多辛  
RoundTripper 是 net/http 包中的一个接口,定义了处理 HTTP 请求返回和响应的方法,是 http.Client 结构体中执行 http 请求的核心部分,本文将详细的给大家介绍Golang RoundTripper接口,需要的朋友可以参考下

RoundTripper 是什么? 

RoundTripper 是 net/http 包中的一个接口,定义了处理 HTTP 请求返回和响应的方法,是 http.Client 结构体中执行 http 请求的核心部分。接口定义如下:

type RoundTripper interface {
	RoundTrip(*Request) (*Response, error)
}

只定义了 RoundTrip 一个方法,用于执行单个 HTTP 事务,发送请求数据并返回对应的响应数据。RoundTrip 不应该去解析响应数据,特别是如果获得了响应数据后,RoundTrip 必须返回值为 nil 的 error(不管响应的HTTP状态码是什么)。如果没有获得响数据,应返回一个非 nil 的 error,RoundTrip 也不应该尝试处理更高级的协议细节,如重定向、身份验证或 cookie 等。

除了消费和关闭请求的 Body 之外,RoundTrip 不应该修改请求,RoundTrip 可以在单独的 goroutine 中读取请求的字段。在 Response Body 被关闭之前,调用方不应该改变或重用请求。RoundTrip 必须始终关闭 body(即使遇到 error),但根据实现,即使在 RoundTrip 返回之后也可以在单独的 goroutine 中关闭。

使用场景

借助 RoundTripper 可以在每个请求中添加特定的 header 或者对返回的响应数据进行特定的处理,例如记录日志或根据返回的状态码执行对应逻辑。接下来看一个用于实现链路追踪功能,只需要实现 RoundTripper 接口,在执行 HTTP 请求的同时,收集遥测数据,如请求的持续时间、状态码等,这些数据可以用于性能监控和故障排查。实现 RoundTripper 接口的示例代码如下:

package http_otel
import (
	"net/http"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/codes"
)
type OtelRoundTripper struct {
	original http.RoundTripper
}
func (ort *OtelRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
	tracer := otel.Tracer("")
	ctx, span := tracer.Start(req.Context(), req.URL.Path)
	defer span.End()
	req = req.WithContext(ctx)
	resp, err := ort.original.RoundTrip(req)
	if err != nil {
		span.RecordError(err)
		span.SetStatus(codes.Error, err.Error())
	} else {
		attrs := []attribute.KeyValue{
			{
				Key:   "http.status_code",
				Value: attribute.IntValue(resp.StatusCode),
			},
			{
				Key:   "http.method",
				Value: attribute.StringValue(req.Method),
			},
			{
				Key:   "http.route",
				Value: attribute.StringValue(req.URL.RequestURI()),
			},
			{
				Key:   "http.scheme",
				Value: attribute.StringValue(req.URL.Scheme),
			},
			{
				Key:   "http.user_agent",
				Value: attribute.StringValue(req.UserAgent()),
			},
		}
		span.SetAttributes(attrs...)
	}
	return resp, err
}
func New() *OtelRoundTripper {
	return &OtelRoundTripper{
		original: tripper,
	}
}

使用 net/http 包实现链路追踪代码如下:

package main
import (
    "bytes"
    "fmt"
    "xxx/http-otel"
    "io"
    "net/http"
)
func main() {
    reader := bytes.NewReader([]byte(`{"foo":"bar"}`))
    request, err := http.NewRequest("POST", "http://xxx.com/user/list", reader)
    if err != nil {
       panic(err)
    }
    request = request.WithContext(traceCtx) // traceCtx 指上文的 context,这里使用伪代码作演示
    request.Header.Set("Content-Type", "application/json")
    client := http.Client{Transport: http_otel.New()}
    resp, err := client.Do(request)
    if err != nil {
       panic(err)
    }
    defer resp.Body.Close()
    b, err := io.ReadAll(resp.Body)
    fmt.Println(string(b), err)
}

首先定义了一个用于实现链路追踪功能的 OtelRoundTripper 结构体,然后实现了 RoundTrip 方法。在 RoundTrip 方法中,首先开启一个新的 trace span,并且将追踪的信息编码到 HTTP 请求的 header 中。在请求完成后,将返回的 HTTP 响应信息记录到 trace 中,并返回 HTTP 响应数据。

小结

RoundTripper 接口的强大之处在于能够以简单且可扩展的方式自定义和控制 HTTP 请求的处理。无论是添加特定的 header、处理响应还是执行其他更高级的逻辑,都可以借助 RoundTripper 来实现。

以上就是详解Golang net/http包中的RoundTripper接口的详细内容,更多关于Golang RoundTripper接口的资料请关注脚本之家其它相关文章!

相关文章

  • Go Protobuf生成代码详解

    Go Protobuf生成代码详解

    文章介绍了如何使用Go语言的protoc-gen-go插件生成Protocol Buffers(protobuf)代码,并详细说明了生成文件的输出路径、Go包导入路径的配置、API等级的选择、并发规则以及字段生成规则等工程化选项
    2025-11-11
  • 详解golang碎片整理之 fmt.Scan

    详解golang碎片整理之 fmt.Scan

    本文介绍了从golang语言中fmt包从标准输入获取数据的Scan系列函数、从io.Reader中获取数据的Fscan系列函数以及从字符串中获取数据的Sscan系列函数的用法,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • 用Go语言编写一个简单的分布式系统

    用Go语言编写一个简单的分布式系统

    这篇文章主要介绍了用Go语言编写一个简单的分布式系统,文中的代码示例讲解的非常详细,对我们的学习或工作有一定的帮助,感兴趣的小伙伴跟着小编一起来看看吧
    2023-08-08
  • Go语言通过smtp发送邮件的方法

    Go语言通过smtp发送邮件的方法

    这篇文章主要介绍了Go语言通过smtp发送邮件的方法,涉及Go语言发送邮件的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go 使用环境变量的实现小结

    Go 使用环境变量的实现小结

    作为软件开发人员,在项目中管理配置变量的重要性,本文主要介绍在 Golang 中处理环境变量的强大工具 github.com/joho/godotenv 包,利用这个包,你可以简化处理 .env 文件的过程,感兴趣的可以了解一下
    2025-11-11
  • 浅谈Golang数据竞态

    浅谈Golang数据竞态

    本文主要介绍了浅谈Golang数据竞态,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • Go中strings包的基本使用示例代码

    Go中strings包的基本使用示例代码

    本文详细介绍了Go语言中strings包的基本使用方法,包括字符串的前缀、后缀判断,字符串包含、索引查找、字符串替换、计数、重复、大小写转换、修剪、分割、拼接以及数据类型转换等功能,示例代码丰富,适合初学者和需要使用字符串处理功能的开发者参考学习
    2024-10-10
  • Golang在图像中绘制矩形框的示例代码

    Golang在图像中绘制矩形框的示例代码

    这篇文章主要介绍了Golang在图像中绘制矩形框的示例代码,文中有详细的代码示例供大家参考,具有一定的参考价值,需要的朋友可以参考下
    2008-08-08
  • Go使用WebSocket实现一个公域聊天室

    Go使用WebSocket实现一个公域聊天室

    公域聊天室是一种实时通信服务,所有用户连接到同一个公共房间,本文下面就介绍一下Go使用WebSocket实现一个公域聊天室,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-03-03
  • 简化Go开发提高生产力的强大工具及使用详解

    简化Go开发提高生产力的强大工具及使用详解

    作为 Go 开发人员,应该都知道维持简洁高效开发工作流程的重要性,为了提高工作效率和代码质量,简化开发流程并自动执行重复性任务至关重要,在本文中,我们将探讨一些强大的工具和技术,它们将简化 Go 开发过程,助力您的编码之旅
    2023-10-10

最新评论