文章目录
- [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))
}
💡 实现思路
- 使用
http.NewRequestWithContext
构建 HTTP 请求对象。 - 通过
client.Do(req)
发送请求。 - 动态设置请求头,支持不同的 Content-Type。
- 处理查询参数,方便 GET 请求传参。
- 读取响应体,处理服务器返回的数据。
🚀 示例
完整示例:
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 请求,减少模板代码的编写,提升开发效率。