Help us shape the future of Go! Take the 2026 Go Developer Survey

httpjson

package
v0.31.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package httpjson stdlib-only 的 HTTP+JSON 调用纪律单源:ctx 感知构造请求 → 执行 → 限容读体(读错误不吞)→ 状态码检查(错误体 rune 安全截断,不腰斩 UTF-8)→ JSON 解码,外加可选的指数退避重试与服务端 Retry-After 建议捕获。

与 network/httpx 的分工(同名不同物):那侧是 Hertz 底座的服务间调用基础 设施(服务发现/熔断/指标/追踪,编译期即拉 hertz+prometheus+gobreaker+otel 依赖链);本包纯函数、调用方注入 *http.Client——被嵌入的 SDK 与外部 API 调用方(LLM 网关、第三方开放平台)复用,不把微服务全家桶拖进依赖树。 收编自 agentkit/httpx(v0.10.41 起单源在此,agentkit 侧消费本包)。

Index

Constants

View Source
const MaxServerRetryAfter = 5 * time.Minute

MaxServerRetryAfter 服务端退避建议的可信上限:超过 5 分钟的建议不直接采信 (长时间限流应交由上层 failover/切换处置,而非原地等)。

Variables

This section is empty.

Functions

func DoJSON

func DoJSON(ctx context.Context, client *http.Client, req Request, out any) error

DoJSON 执行请求并把 2xx 响应体解码进 out。非 2xx 返回带状态码与响应体摘要 (rune 安全截断到 200 字符)的错误;解码失败返回包装后的解析错误。 错误不带包前缀返回,调用方以自己的包前缀包装一次。

func DoJSONWithRetry

func DoJSONWithRetry(ctx context.Context, client *http.Client, reqFn func() (Request, error), cfg RetryConfig, out any) error

DoJSONWithRetry 带重试的 HTTP+JSON 调用。

reqFn 每次尝试重新构造 Request(请求体流不可重读,且调用方可能希望每轮 刷新签名头);reqFn 自身报错视为调用方参数问题,立即返回不重试。 重试间指数退避 + Jitter 抖动;ctx 取消/超时立即返回 ctx.Err()。 配合 WithRetryAfterSink + RetryAfterTransport 可让 429 的服务端建议 参与退避取舍(调用方在 wait 前经 SelectRetryDelay(RetryAfterFrom(ctx)) 采信)。

func RetryAfterFrom

func RetryAfterFrom(ctx context.Context) time.Duration

RetryAfterFrom 读取最近一次 429 的服务端建议(0 = 无)。重试环在计算退避时调用。 sink 不随尝试清除:仅对本次失败确为限流的场景采信(陈旧建议不得套用到 非限流错误上),门控归调用方的重试策略。

func SelectRetryDelay

func SelectRetryDelay(local, hint time.Duration) time.Duration

SelectRetryDelay 退避取舍(「合理性钳制」):服务端建议 >0 且 (≤MaxServerRetryAfter 或 < 本地曲线值)→ 采信建议;否则本地曲线。

func WithRetryAfterSink

func WithRetryAfterSink(ctx context.Context) context.Context

WithRetryAfterSink 在 ctx 注入 sink(重试环上游调用一次;传输层据此回写)。

Types

type RawResponse added in v0.29.0

type RawResponse struct {
	// StatusCode 是 HTTP 状态码(不判 2xx,由调用方按自己的语义映射)。
	StatusCode int
	// Body 是响应体原始字节(最多 limit 字节)。
	Body []byte
	// Truncated 报告 Body 是否因超过 limit 而被截断。
	//
	// 截断本身是刻意的(limit 防内存放大),但**必须可观测**——否则调用方
	// 会把「半截报文」当成完整报文用。
	Truncated bool
}

RawResponse 是 DoRaw 的原始响应结果。

func DoRaw added in v0.28.1

func DoRaw(ctx context.Context, client *http.Client, req Request, limit int64) (RawResponse, error)

DoRaw 执行请求并返回**原始**状态码与响应体:不判 2xx、不解 JSON。

适用面(DoJSON 不适用的那些):

  • 调用方要**按状态码映射自己的语义**(如 404/409 → 各自的哨兵错误);
  • 调用方要把**原文**报文带进错误文案(DoJSON 的错误体是 rune 安全截断到 200 字符的**摘要**,不是原文)。

limit 是读体上限(字节):<=0 时用包级 maxBody。调用方应按自己的报文体量 给一个够用又防内存放大的值(如 8KB)。**超过 limit 的部分会被截断**, 且截断**在 RawResponse.Truncated 里如实标记**——调用方据此判断拿到的是 完整报文还是半截(截断对调用方不可见是最容易埋雷的形态:拿半截 JSON 去 解析会得到难以定位的解析错误,拿半截报文进错误文案会丢服务端说明)。

传输层错误(连不上/超时)返回 err,status/body 无意义;HTTP 层错误(任何状态码) 一律返回 nil err,由调用方按状态码自行判定。

type Request

type Request struct {
	// Method HTTP 方法(空 = GET)。
	Method string
	// URL 完整地址(含 query)。
	URL string
	// Body 请求体(nil = 无请求体;JSON 调用方自行 Marshal)。
	Body []byte
	// Header 鉴权/Content-Type 等请求头注入钩子(可 nil)。
	Header func(h http.Header)
}

Request 一次 HTTP+JSON 调用的描述。

type RetryAfterTransport

type RetryAfterTransport struct {
	Base http.RoundTripper
}

RetryAfterTransport 透明捕获 429 的 Retry-After 头。响应体不做任何改写—— 上层错误构造不受影响。Base 为 nil 时用 http.DefaultTransport。

func (RetryAfterTransport) RoundTrip

func (t RetryAfterTransport) RoundTrip(req *http.Request) (*http.Response, error)

type RetryConfig

type RetryConfig struct {
	// MaxAttempts 总尝试次数(含首次;<1 视为 1)。
	MaxAttempts int
	// BaseDelay 首次重试延迟(<=0 取 200ms),按尝试轮次指数退避。
	BaseDelay time.Duration
	// MaxDelay 单次重试延迟上限(<=0 取 2s)。
	MaxDelay time.Duration
	// Jitter 随机抖动幅度(防惊群;<0 取 0)。
	Jitter time.Duration
	// Retryable 自定义可重试判定(nil = 默认:网络超时或 HTTP 5xx/429 可重试;
	// 4xx 参数错、响应解析失败不重试)。
	Retryable func(err error) bool
}

RetryConfig 一次重试策略(零值 = 仅执行一次,不重试)。

type StatusError

type StatusError struct {
	Code int
	Body string
}

StatusError 非 2xx 响应错误:供重试判定等按状态码分类(errors.As 提取)。

func (*StatusError) Error

func (e *StatusError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL