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 请求,包括 GET、POST、PUT 和 DELETE 等常见操作。通过这个工具包,可以轻松管理 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 请求,减少模板代码的编写,提升开发效率。

相关推荐
excel9 小时前
IndexNow:让搜索引擎更快发现网站更新的主动通知协议
前端·后端·架构
Json____10 小时前
用 FastAPI + Vue3 打造一套完整的在线考试系统:从组卷到阅卷的业务闭环实践
后端·node.js·fastapi·it学习·wwwoop.com
Codiggerworld10 小时前
从“装一套协议”到“扔进终端”:MCP 与 CLI 的 Agent 工具层之争
人工智能·程序人生·ai编程
小灰灰搞电子11 小时前
Rust+Slint 实现FTP客户端调试助手源码分享
开发语言·后端·rust
秋天的怀念_David11 小时前
算法一千零一夜 · 第十三夜 幻方,武侠世界里的数学迷宫
java·程序人生·算法
专业程序开发源11 小时前
springboot欧缇蔓月子中心管理系统82697-计算机课程设计、毕业设计
java·spring boot·后端·python·spring·django·课程设计
卷无止境11 小时前
面向arm64桌面客户端开发全景:语言、框架与生态
后端·python
秋天的怀念_David12 小时前
算法一千零一夜 · 第十四夜 幻方与奇妙的二进制
java·程序人生·算法
IT_陈寒12 小时前
JavaScript的闭包陷阱,这个坑我躺了三天才爬出来
前端·人工智能·后端
用户83562907805112 小时前
如何使用 Python 对 Excel 数据进行分组和分级显示
后端·python