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

文章目录

  • [Go 语言封装 HTTP 请求的 Curl 工具包](#Go 语言封装 HTTP 请求的 Curl 工具包)
    • [🏗️ 工具包结构简介](#🏗️ 工具包结构简介)
    • [🌟 功能实现](#🌟 功能实现)
      • [1. 设置请求头](#1. 设置请求头)
      • [2. 构建请求](#2. 构建请求)
      • [3. 发送请求](#3. 发送请求)
      • [4. 发送 GET 请求](#4. 发送 GET 请求)
      • [5. 发送 POST 请求](#5. 发送 POST 请求)
      • [6. 发送 PUT 请求](#6. 发送 PUT 请求)
      • [7. 发送 DELETE 请求](#7. 发送 DELETE 请求)
      • [8. 读取响应体](#8. 读取响应体)
    • [💡 实现思路](#💡 实现思路)
    • [🚀 示例](#🚀 示例)
    • [🏆 总结](#🏆 总结)

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

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


🏗️ 工具包结构简介

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

核心结构体定义

go 复制代码
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,支持动态设置。

初始化函数

go 复制代码
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 请求头:

go 复制代码
func (c *Curl) SetHeader(key, value string) {
    c.headers[key] = value
}

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

go 复制代码
curl.SetHeader("Content-Type", "application/json")

2. 构建请求

go 复制代码
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. 发送请求

go 复制代码
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 请求获取资源:

go 复制代码
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)
}

示例:

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

5. 发送 POST 请求

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

go 复制代码
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)
}

示例:

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

6. 发送 PUT 请求

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

go 复制代码
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)
}

示例:

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

7. 发送 DELETE 请求

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

go 复制代码
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)
}

示例:

go 复制代码
response, err := curl.Delete(context.TODO(), "/user")

8. 读取响应体

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

go 复制代码
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)
}

示例:

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

💡 实现思路

  1. 使用 http.NewRequestWithContext 构建 HTTP 请求对象。
  2. 通过 client.Do(req) 发送请求。
  3. 动态设置请求头,支持不同的 Content-Type。
  4. 处理查询参数,方便 GET 请求传参。
  5. 读取响应体,处理服务器返回的数据。

🚀 示例

完整示例:

go 复制代码
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 请求,减少模板代码的编写,提升开发效率。

相关推荐
canonical_entropy1 分钟前
最小变更成本 vs 最小信息表达:第一性原理的比较
后端
渣哥1 分钟前
代理选错,性能和功能全翻车!Spring AOP 的默认技术别再搞混
javascript·后端·面试
间彧17 分钟前
Java泛型详解与项目实战
后端
间彧27 分钟前
PECS原则在Java集合框架中的具体实现有哪些?举例说明
后端
间彧29 分钟前
Java 泛型擦除详解和项目实战
后端
间彧33 分钟前
在自定义泛型类时,如何正确应用PECS原则来设计API?
后端
间彧34 分钟前
能否详细解释PECS原则及其在项目中的实际应用场景?
后端
武子康1 小时前
大数据-132 Flink SQL 实战入门 | 3 分钟跑通 Table API + SQL 含 toChangelogStream 新写法
大数据·后端·flink
九江Mgx1 小时前
使用 Go + govcl 实现 Windows 资源管理器快捷方式管理器
windows·golang·govcl
李辰洋1 小时前
go tools安装
开发语言·后端·golang