Go语言封装HTTP请求的Curl工具包详解

 更新时间:2025年03月11日 08:32:21   作者:熬了夜的程序员  
在 Go 语言开发中,与 HTTP 服务进行交互是非常常见的需求,本文将分享一个用 Go 语言封装的 Curl 工具包,它提供了简洁易用的接口来进行 HTTP 请求,需要的可以了解下

在 Go 语言开发中,与 HTTP 服务进行交互是非常常见的需求。本文将分享一个用 Go 语言封装的 Curl 工具包,它提供了简洁易用的接口来进行 HTTP 请求,包括 GET、POST、PUT 和 DELETE 等常见操作。通过这个工具包,可以轻松管理 HTTP 请求头、查询参数和请求体,并处理响应。

工具包结构简介

在这个 curl 工具包中,主要定义了一个 Curl 结构体,封装了 HTTP 客户端的常见操作。

核心结构体定义

type Curl struct {
    client  *http.Client      // http client
    baseURL string            // base url
    headers map[string]string // headers
}

client:使用 http.Client 发送 HTTP 请求。

baseURL:基础 URL,便于在请求时自动拼接路径。

headers:一个存储 HTTP 请求头的 map,支持动态设置。

初始化函数

func NewCurl(baseURL string, timeout time.Duration) *Curl {
    return &Curl{
        client: &http.Client{
            Timeout: timeout,
        },
        baseURL: strings.TrimSuffix(baseURL, "/"),
        headers: make(map[string]string),
    }
}

baseURL:传入基础 URL。

timeout:设置超时时间。

功能实现

1. 设置请求头

SetHeader 用于设置 HTTP 请求头:

func (c *Curl) SetHeader(key, value string) {
    c.headers[key] = value
}

可以通过如下方式动态设置请求头:

curl.SetHeader("Content-Type", "application/json")

2. 构建请求

func (c *Curl) buildRequest(ctx context.Context, method, urlPath string, queryParams map[string]string, body io.Reader) (*http.Request, error) {
    // 处理完整的 URL
    fullURL := c.baseURL + urlPath
    if queryParams != nil {
        query := url.Values{}
        for key, value := range queryParams {
            query.Add(key, value)
        }
        fullURL += "?" + query.Encode()
    }

    // 创建请求
    req, err := http.NewRequestWithContext(ctx, method, fullURL, body)
    if err != nil {
        return nil, err
    }

    // 设置请求头
    for key, value := range c.headers {
        req.Header.Set(key, value)
    }

​​​​​​​    return req, nil
}

3. 发送请求

func (c *Curl) doRequest(req *http.Request) (*http.Response, error) {
    resp, err := c.client.Do(req)
    if err != nil {
        return nil, err
    }
    return resp, nil
}

4. 发送 GET 请求

Get 方法通过 HTTP GET 请求获取资源:

func (c *Curl) Get(ctx context.Context, urlPath string, queryParams map[string]string) (*http.Response, error) {
    req, err := c.buildRequest(ctx, http.MethodGet, urlPath, queryParams, nil)
    if err != nil {
        return nil, err
    }
    return c.doRequest(req)
}

示例:

response, err := curl.Get(context.TODO(), "/user", map[string]string{"id": "123"})

5. 发送 POST 请求

Post 方法通过 HTTP POST 请求提交数据:

func (c *Curl) Post(ctx context.Context, urlPath string, body []byte) (*http.Response, error) {
    req, err := c.buildRequest(ctx, http.MethodPost, urlPath, nil, bytes.NewBuffer(body))
    if err != nil {
        return nil, err
    }
    return c.doRequest(req)
}

示例:

data := []byte(`{"name":"Alice"}`)
response, err := curl.Post(context.TODO(), "/user", data)

6. 发送 PUT 请求

Put 方法通过 HTTP PUT 请求更新资源:

func (c *Curl) Put(ctx context.Context, urlPath string, body []byte) (*http.Response, error) {
    req, err := c.buildRequest(ctx, http.MethodPut, urlPath, nil, bytes.NewBuffer(body))
    if err != nil {
        return nil, err
    }
    return c.doRequest(req)
}

示例:

data := []byte(`{"age":30}`)
response, err := curl.Put(context.TODO(), "/user", data)

7. 发送 DELETE 请求

Delete 方法通过 HTTP DELETE 请求删除资源:

func (c *Curl) Delete(ctx context.Context, urlPath string) (*http.Response, error) {
    req, err := c.buildRequest(ctx, http.MethodDelete, urlPath, nil, nil)
    if err != nil {
        return nil, err
    }
    return c.doRequest(req)
}

示例:

response, err := curl.Delete(context.TODO(), "/user")

8. 读取响应体

ReadResponseBody 读取 HTTP 响应体并返回字节数组:

func ReadResponseBody(resp *http.Response) ([]byte, error) {
    defer func(Body io.ReadCloser) {
        err := Body.Close()
        if err != nil {
            fmt.Printf("close response body failed: %v\n", err)
        }
    }(resp.Body)
    return io.ReadAll(resp.Body)
}

示例:

body, err := ReadResponseBody(response)
if err != nil {
    fmt.Println("Read response body error:", err)
} else {
    fmt.Println("Response body:", string(body))
}

实现思路

使用 http.NewRequestWithContext 构建 HTTP 请求对象。

通过 client.Do(req) 发送请求。

动态设置请求头,支持不同的 Content-Type。

处理查询参数,方便 GET 请求传参。

读取响应体,处理服务器返回的数据。

示例

完整示例

curl := NewCurl("https://example.com", 10*time.Second)
curl.SetHeader("Authorization", "Bearer token")
resp, err := curl.Get(context.TODO(), "/api/resource", map[string]string{"key": "value"})
if err != nil {
    log.Fatalf("Failed to send GET request: %v", err)
}

body, err := ReadResponseBody(resp)
if err != nil {
    log.Fatalf("Failed to read response: %v", err)
}

fmt.Println("Response:", string(body))

总结

通过封装 Curl 结构体,简化了 Go 语言中与 HTTP 服务的交互过程,提供了灵活的配置和扩展能力。通过这种封装,可以快速集成 HTTP 请求,减少模板代码的编写,提升开发效率。

到此这篇关于Go语言封装HTTP请求的Curl工具包详解的文章就介绍到这了,更多相关Go封装HTTP请求内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言的互斥锁的详细使用

    Go语言的互斥锁的详细使用

    本文主要介绍了Go语言的互斥锁的详细使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Go语言文件读写操作案例详解

    Go语言文件读写操作案例详解

    这篇文章主要为大家介绍了Go语言文件读写操作案例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Golang Gorm 更新字段save、update、updates

    Golang Gorm 更新字段save、update、updates

    在gorm中,批量更新操作可以通过使用Update方法来实现,本文主要介绍了Golang Gorm 更新字段save、update、updates,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • Go处理包含多种引号的字符串的几种方法

    Go处理包含多种引号的字符串的几种方法

    在Go中,有几种方式可以处理包含多种引号的字符串,以确保代码的可读性和正确性,本文将给大家详细介绍了这几种处理方式,并通过代码示例讲解的非常详细,需要的朋友可以参考下
    2024-04-04
  • Go语言中slice的用法实例分析

    Go语言中slice的用法实例分析

    这篇文章主要介绍了Go语言中slice的用法,实例分析了slice的功能及使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go中runtime.Caller的使用

    Go中runtime.Caller的使用

    这篇文章主要介绍了Go中runtime.Caller的使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-03-03
  • go语言实现银行卡号Luhn校验

    go语言实现银行卡号Luhn校验

    这篇文章主要为大家介绍了go语言Luhn校验测试银行卡号码的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • 基于Golang container/list实现LRU缓存

    基于Golang container/list实现LRU缓存

    Least Recently Used (LRU) ,即逐出最早使用的缓存,这篇文章主要为大家介绍了如何基于Golang container/list实现LRU缓存,感兴趣的可以了解下
    2023-08-08
  • 如何使用Goland IDE go mod 方式构建项目

    如何使用Goland IDE go mod 方式构建项目

    这篇文章主要介绍了如何使用Goland IDE go mod 方式构建项目,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • 深入理解Go中rune类型的使用

    深入理解Go中rune类型的使用

    本文主要介绍了深入理解Go中rune类型的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-02-02

最新评论