请问我们是否可以为Go http客户端创建"中间件"功能?例如,我想添加一个日志(log)函数,以便记录每个发送的请求,或者添加setAuthToken,以便将令牌添加到每个请求的头部.

推荐答案

您可以在HTTP客户端中使用Transport参数来实现此效果,并使用合成模式,使用以下事实:

  • http.Client.Transport定义了处理所有HTTP请求的函数;
  • http.Client.Transport具有接口类型http.RoundTripper,因此可以用您自己的实现替换;

例如:

package main

import (
    "fmt"
    "net/http"
)

// This type implements the http.RoundTripper interface
type LoggingRoundTripper struct {
    Proxied http.RoundTripper
}

func (lrt LoggingRoundTripper) RoundTrip(req *http.Request) (res *http.Response, e error) {
    // Do "before sending requests" actions here.
    fmt.Printf("Sending request to %v\n", req.URL)

    // Send the request, get the response (or the error)
    res, e = lrt.Proxied.RoundTrip(req)

    // Handle the result.
    if (e != nil) {
        fmt.Printf("Error: %v", e)
    } else {
        fmt.Printf("Received %v response\n", res.Status)
    }

    return
}

func main() {
    httpClient := &http.Client{
        Transport: LoggingRoundTripper{http.DefaultTransport},
    }
    httpClient.Get("https://example.com/")
}

你想改名字就改吧,我没想太久.

Go相关问答推荐

获取k8s群集作用域运算符的命名空间

如何使用gopher-lua定义一个Lua函数,该函数有一个预定义的表作为param,Lua脚本可以在其中访问该函数中的表?

什么东西逃到了堆里?

go中跨域自定义验证的问题

Go 1.20 中如何计算连接错误?

Golang telegram 机器人

通过 Terraform 中的 MapNestedAtribute 进行迭代

如何使用gosdk在Dynamodb中进行UpdateItem时,将ValueBuilder对象声明为StringSet类型?

带有前导零的整数参数被 flag.IntVar 解析为八进制

Go Programming Language书上的例子server2错了吗?

从给定顶点查找图形中所有闭合路径的算法

GoLang: gocui 边框 colored颜色

为什么互斥量比 golang 中的通道慢?

具有未导出字段的 struct 类型之间的转换

为什么 Go 被认为是部分抢占式的?

为什么 0 big.Int 的 .Bytes() 值是空切片?

将 Golang Gin 与 AWS Lambda 和无服务器与代理路径一起使用

无限期运行 Go routine (完成后重新启动)

函数的递归调用以 goroutine 和惯用方式开始,以在所有工作 goroutine 完成时继续调用者

为什么 go-cmp Equal() 说 struct 不是完全相等的,即使所有字段都非常相等?