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

news2025/3/11 8:18:54

文章目录

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

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

在 Go 语言开发中,与 HTTP 服务进行交互是非常常见的需求。本文将分享一个用 Go 语言封装的 Curl 工具包,它提供了简洁易用的接口来进行 HTTP 请求,包括 GETPOSTPUTDELETE 等常见操作。通过这个工具包,可以轻松管理 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))
}

💡 实现思路

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

🚀 示例

完整示例:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2313119.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】函数重载与nullptr

1、函数重载 C支持在同一个作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是形参个数不同或者类型不同。这样C函数调用就表现出了多态行为,使用更灵活。C语言是不支持同一作用域中出现同名函数的。 代码: 形参类型不…

处理动态分页:自动翻页与增量数据抓取策略-数据议事厅

一、案例场景 Lily(挥舞着数据报表):“用户反馈我们的股票舆情分析总是缺失最新跟帖!这些动态分页像狡猾的狐狸,每次抓取都漏掉关键数据!” 小王(调试着爬虫代码):“传…

用android studio模拟器,模拟安卓手机访问网页,使用Chrome 开发者工具查看控制台信息

web 网页项目在安卓手机打开时出现问题,想要查看控制台调试信息。记录一下使用android studio 模拟器访问的方式。 步骤如下: 1.安装android studio,新增虚拟设备(VDM- virtual device manager) 点击Virtual Device Manager后会…

【Linux内核系列】:深入理解缓冲区

🔥 本文专栏:Linux 🌸作者主页:努力努力再努力wz ★★★ 本文前置知识: 文件系统以及相关系统调用接口 输入以及输出重定向 那么在此前的学习中,我们了解了文件的概念以及相关的系统调用接口,并…

【互联网性能指标】QPS/TPS/PV/UV/IP/GMV/DAU/MAU/RPS

📕我是廖志伟,一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》(基础篇)、(进阶篇)、(架构篇)清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、…

【微知】如何根据内核模块ko查看所依赖其他哪些模块?(modinfo rdma_ucm |grep depends)

背景 有些情况下查看某个模块被哪些模块依赖可以用lsmod看到后面的列表,但是反向查看就要麻烦一些,比如某个模块依赖哪些其他模块?通过modinfo xxx.ko获取里面的depends相关信息 方法 modinfo rdma_ucm |grep depends实操 实操前先看依赖…

Linux安装ComfyUI

Linux安装ComfyUI 1. ComfyUI2. 放置模型文件3. 创建python虚拟环境3.1 删除 Conda 虚拟环境 4. python虚拟环境,安装PyTorch5. 安装依赖6. 运行7. 打开8. 下载模型 移动到路径 1. ComfyUI # cat /etc/issue Ubuntu 20.04.6 LTS \n \lmkdir comfyUI cd comfyUI/git…

订阅指南:用关键指标驱动业务增长

分析订阅业务远非看似简单。仅仅增加订阅数可能并不比维持一批忠实用户更有利可图。深入分析订阅数据及其背后的运作机制,将帮助您优化产品决策、预测收入并促进增长。本文将为您解读关键订阅指标的实际意义,并展示如何通过订阅宝这一专业工具&#xff0…

【开发学习】如何使用deepseek创建记录事件时间的PC应用程序

本文记录了尝试使用deepseek创建应用程序的过程,实现记录事件&时间的PC应用程序,包括创建代码、测试及调整。 目的:创建一个应用,用户输入文本提交,应用记录下时间和文本,数据留存在excel和应用程序中。…

OSPF-单区域的配置

一、单区域概念: 单区域OSPF中,整个网络被视为一个区域,区域ID通常为0(骨干区域)。所有的路由器都在这个区域内交换链路状态信息。 补充知识点: OSPF为何需要loopback接口: 1.Loopback接口的…

【2025力扣打卡系列】0-1背包 完全背包

坚持按题型打卡&刷&梳理力扣算法题系列,语言为python3,Day5 0-1背包【目标和】 有n个物品,第i个物品的体积为w[i], 价值为v[i]。每个物品至多选一个,求体积和不超过capacity时的最大价值和常见变形 至多装capacity&#x…

分布式锁—Redisson的同步器组件

1.Redisson的分布式锁简单总结 Redisson分布式锁包括:可重入锁、公平锁、联锁、红锁、读写锁。 (1)可重入锁RedissonLock 非公平锁,最基础的分布式锁,最常用的锁。 (2)公平锁RedissonFairLock 各个客户端尝试获取锁时会排队,按照队…

OpenEuler24.x下ZABBIX6/7实战1:zabbix7.2.4安装及zabbix-agent安装

兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 1 安装及准备 先决条件:建议使用CentOS8以上的操作系统。 CentOS8.5.2111内核版本为 图1- 1 华为OpenEuler24(以后简称OE24)的内核为 [rootzbxsvr ~]# uname -r 5.10.0-…

ROS实践一构建Gazebo机器人模型文件urdf

URDF(Unified Robot Description Format)是一种基于XML的格式,用于描述机器人模型的结构、关节、连杆和传感器信息,并可以与Gazebo、RViz等仿真环境结合使用。 一、基础语法 1. urdf文件组成 URDF 主要由以下几个核心元素&#…

C++学习——哈希表(一)

文章目录 前言一、哈希表的模板代码二、哈希计数器三、哈希表中的无序映射四、哈希表的总结 前言 本文为《C学习》的第11篇文章&#xff0c;今天学习最后一个数据结构哈希表&#xff08;散列表&#xff09;。 一、哈希表的模板代码 #include<iostream> using namespace…

DeepSeek R1在医学领域的应用与技术分析(Discuss V1版)

DeepSeek R1作为一款高性能、低成本的国产开源大模型,正在深刻重塑医学软件工程的开发逻辑与应用场景。其技术特性,如混合专家架构(MoE)和参数高效微调(PEFT),与医疗行业的实际需求紧密结合,推动医疗AI从“技术驱动”向“场景驱动”转型。以下从具体业务领域需求出发,…

Git 如何配置多个远程仓库和免密登录?

自我简介&#xff1a;4年导游&#xff0c;10年程序员&#xff0c;最近6年一直深耕低代码领域&#xff0c;分享低代码和AI领域见解。 通用后台管理系统 代号&#xff1a;虎鲸 缘由 每次开发后台界面都会有很多相同模块&#xff0c;尝试抽离出公共模块作为快速开发的基座。 目标…

【Linux篇】从冯诺依曼到进程管理:计算机体系与操作系统的核心逻辑

&#x1f4cc; 个人主页&#xff1a; 孙同学_ &#x1f527; 文章专栏&#xff1a;Liunx &#x1f4a1; 关注我&#xff0c;分享经验&#xff0c;助你少走弯路&#xff01; 文章目录 1.冯诺依曼体系结构存储分级理解数据流动 2. 操作系统(Operator System)2.1 概念2.2 设计OS的…

【Linux docker】关于docker启动出错的解决方法。

无论遇到什么docker启动不了的问题 就是 查看docker状态sytemctl status docker查看docker日志sudo journalctl -u docker.service查看docker三个配置文件&#xff1a;/etc/docker/daemon.json&#xff08;如果存在&#xff09; /etc/systemd/system/docker.service&#xff…

【医院内部控制专题】7.医院内部控制环境要素剖析(三):人力资源政策

医院成本核算、绩效管理、运营统计、内部控制、管理会计专题索引 一、引言 在当今医疗行业竞争日益激烈的背景下,医院内部控制的重要性愈发凸显。内部控制作为医院管理的关键组成部分,对于保障医院资产安全、提高会计信息质量、提升运营效率以及实现战略目标起着至关重要的…