Learn HTTP Clients in Go(Boot.dev)
Boot.dev 的 Learn HTTP Clients in Go 课程框架笔记——用 net/http 发起请求、处理响应、客户端模式,依赖 HTTP 协议与 net/http 前置。
Learn HTTP Clients in Go(Boot.dev)
[!info] 关联笔记
- 所属路线:Go Web 与后端 · Go 标准库与应用
- 来源平台:Boot.dev
- 依赖前置:boot-dev-learn-http-protocol-in-go · net/http
- 后续课程:boot-dev-learn-http-servers-in-go
概览
boot.dev 上的 learn http clients in go 课程 真就是在讲,go 作为一个 client,应该具备的一些知识。
why http
这一章节讲了大致下面内容:
- Go 程序一般使用 HTTP 协议从服务端获取数据,并且数据的类型一般是字节切片。
- 基础的 front-end、back-end、client、server、URL、http等的概念
- go 一般使用自带的 net/http 标准库来进行请求
JSON
- 讲了 JSON定义
- go中从JSON提取数据,
encoding/json库, 主要用于从 io 中处理流式数据
import (
"fmt"
"net/http"
"encoding/json"
)
var issues []Issue // 定义一个 issues
decoder := json.NewDecoder(res.Body) // 创建解码器
if err := decoder.Decode(&issues); err != nil { // 解码器填充 issues
fmt.Println("error decoding response body")
return nil, fmt.Errorf("error creating request: %w", err)
}
json.Unmarshal处理已经有的完整、小型 JSON 数据
// res is an http.Response
defer res.Body.Close()
data, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
var issues []Issue
if err := json.Unmarshal(data, &issues); err != nil {
return nil, err
}
json.Marshalgo struct 转为 JSON 数据map[string]interface{}用于在 go 中灵活处理奇怪的 JSON 数据格式
DNS
net/url go 的用于处理 url 的标准库
parsedURL, err := url.Parse("https://homestarrunner.com/toons")
if err != nil {
fmt.Println("error parsing url:", err)
return
}
parsedURL.Hostname()
// homestarrunner.com
URIs
统一资源定位符,Uniform Resource Identifiers
URI 包含 URN 和 URL
URL struct
http://testuser:testpass@testdomain.com:8080/testpath?testsearch=testvalue#testhash
newParsedURL should return a struct with these fields:
return ParsedURL{
protocol: "http",
username: "testuser",
password: "testpass",
hostname: "testdomain.com",
port: "8080",
pathname: "/testpath",
search: "testsearch=testvalue",
hash: "testhash",
}
Use these fields and methods of the URL struct:
SchemeUser.Username()User.Password()- this method returns two values: the password if set and whether it was setHostname()Port()PathRawQueryFragment
protocol 也叫 scheme, 有多种scheme (http、ftp、mailto、https),不是说有都需要 // , eg: mailto:noreply@jello.app
headers
请求头
主要就是讲通过 net/http 库里面哪些标准的方法去进行一个请求头的获取,怎么创建一个请求,以及如何从一个响应中获取请求头的信息。
// creating a new request
req, err := http.NewRequest("GET", "https://api.example.com/users", nil)
if err != nil {
fmt.Println("error creating request: ", err)
return
}
// setting a header on the new request
req.Header.Set("x-api-key", "123456789")
// making the request
client := http.Client{}
res, err := client.Do(req)
if err != nil {
fmt.Println("error making request: ", err)
return
}
defer res.Body.Close()
// reading a header from the response
header := res.Header.Get("last-modified")
fmt.Println("last modified: ", header)
// deleting a header from the response
res.Header.Del("last-modified")
请求的作用,主要是用来进行一些身份验证之类的功能。
Method
put,post,delete,patch,get 等语义方法
error
在实际的网络开发中,发起请求并不总是顺畅无阻的。背后的核心知识点可以分为以下两大部分:
1. 网络层错误(Network Errors)
这类错误发生在请求根本无法成功送达服务端,或者无法从服务端接收响应的时候。
- 原因:例如 URL 格式错误、DNS 解析失败、无网络连接、连接超时或服务器宕机。
- Go 中的表现:调用
http.Get(url)会直接返回一个非空的err。 - 处理逻辑:此时由于没有成功建立 HTTP 响应,通常不会有 HTTP 状态码(默认为
0),我们需要先检查并处理这个err,不应该继续读取响应体(res.Body)。
2. 应用层/HTTP 协议错误(Non-OK Responses)
这类错误发生在网络连接正常建立,并且服务器也成功返回了 HTTP 响应,但返回的状态码指示请求出了问题。
- 原因:例如请求的资源不存在(
404 Not Found)、未授权访问(401 Unauthorized)、服务器内部报错(500 Internal Server Error)等。 - Go 中的表现:
http.Get(url)返回的err为nil,因为从网络协议角度来看通信是成功的。但是响应对象res中的StatusCode字段会反应具体的状态(如 404、500 等)。 - 处理逻辑:我们需要手动检查状态码。一般情况下,只有
200到299范围内的状态码(如http.StatusOK即 200)才代表业务上的成功。如果不是200系列,我们需要根据res.StatusCode或res.Status(状态文本)单独进行错误处理,并记得关闭响应体defer res.Body.Close()。
path
https
curl
一个工具 jq json 处理工具