httpx

package
v0.0.0-...-92991a5 Latest Latest
Warning

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

Go to latest
Published: Aug 24, 2026 License: Apache-2.0 Imports: 39 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MIMEJSON              = "application/json"
	MIMEXML               = "application/xml"
	MIMEXML2              = "text/xml"
	MIMEPlain             = "text/plain"
	MIMEPOSTForm          = "application/x-www-form-urlencoded"
	MIMEMultipartPOSTForm = "multipart/form-data"
)

常见的 Content-Type MIME 类型。

View Source
const (
	// CodeOK 成功业务码。
	CodeOK = 0
	// MsgOK 成功业务消息。
	MsgOK = "ok"
	// CodeDefaultError 默认错误业务码。
	CodeDefaultError = -1
)
View Source
const (
	// CodeBadRequest 请求参数错误。
	CodeBadRequest = 400
	// CodeUnauthorized 未认证。
	CodeUnauthorized = 401
	// CodeForbidden 无权限。
	CodeForbidden = 403
	// CodeNotFound 资源不存在。
	CodeNotFound = 404
	// CodeRequestEntityTooLarge 请求体过大。
	CodeRequestEntityTooLarge = 413
	// CodeInternalError 服务器内部错误。
	CodeInternalError = 500
	// CodeNotImplemented 未实现。
	CodeNotImplemented = 501
	// CodeServiceUnavailable 服务不可用。
	CodeServiceUnavailable = 503
	// CodeTimeout 请求超时。
	CodeTimeout = 504
)
View Source
const (
	// ContentTypeJSON JSON 内容类型。
	ContentTypeJSON = "application/json; charset=utf-8"
	// ContentTypeXML XML 内容类型。
	ContentTypeXML = "application/xml; charset=utf-8"
	// ContentTypeHTML HTML 内容类型。
	ContentTypeHTML = "text/html; charset=utf-8"
)
View Source
const ContentSecurityHeader = "X-Content-Security"

ContentSecurityHeader 内容安全请求头 `X-Content-Security` 的字段名。

View Source
const HeaderRequestID = "X-Request-Id"

HeaderRequestID 请求 ID 使用的 HTTP Header 名。

Variables

View Source
var (
	// JSON 基于 JSON body 的绑定器。
	JSON BindingBody = jsonBinding{}
	// XML 基于 XML body 的绑定器。
	XML BindingBody = xmlBinding{}
	// Form 基于 Form 表单的绑定器(包含 query 和 post form)。
	Form Binding = formBinding{}
	// Query 基于 URL query 参数的绑定器。
	Query Binding = queryBinding{}
	// Header 基于 HTTP header 的绑定器。
	Header Binding = headerBinding{}
	// Uri 基于 URI 路径参数的绑定器。
	Uri BindingUri = uriBinding{}
)
View Source
var ErrServiceOverloaded = errors.New("httpx: service overloaded")

ErrServiceOverloaded 服务过载时降载器返回的错误。

Functions

func Bind

func Bind(r *http.Request, obj any) error

Bind 根据请求的 Method 和 Content-Type 自动选择绑定器。 GET 请求使用 Form 绑定(query 参数),其他请求根据 Content-Type 选择。

func BindForm

func BindForm(r *http.Request, obj any) error

BindForm 将表单数据(query + post form)绑定到 obj。 使用 `form` 标签匹配字段名。

func BindHeader

func BindHeader(r *http.Request, obj any) error

BindHeader 将 HTTP header 绑定到 obj。 使用 `header` 标签匹配字段名。

func BindJSON

func BindJSON(r *http.Request, obj any) error

BindJSON 将请求 body 作为 JSON 绑定到 obj。

func BindQuery

func BindQuery(r *http.Request, obj any) error

BindQuery 将 URL query 参数绑定到 obj。 使用 `form` 标签匹配字段名。

func BindURI

func BindURI(params map[string]string, obj any) error

BindURI 将 URI 路径参数绑定到 obj。 params 通常来自路由解析的路径参数,如 {"id": "123"}。 使用 `uri` 标签匹配字段名。

func BindURIWithValues

func BindURIWithValues(params map[string][]string, obj any) error

BindURIWithValues 将 map[string][]string 格式的路径参数绑定到 obj。

func BindXML

func BindXML(r *http.Request, obj any) error

BindXML 将请求 body 作为 XML 绑定到 obj。

func ContextWithRequestID

func ContextWithRequestID(ctx context.Context, id string) context.Context

ContextWithRequestID 将 request_id 注入 context。 配合 RequestIDFromContext 使用:

ctx := httpx.ContextWithRequestID(r.Context(), "req-123")
resp := httpx.OkJSONCtx(ctx, w, data)

func MustBind

func MustBind(w http.ResponseWriter, r *http.Request, obj any) error

MustBind 绑定并验证请求数据,出错时写入 HTTP 错误响应。 成功返回 nil,失败返回错误并自动写入响应。

func MustBindForm

func MustBindForm(w http.ResponseWriter, r *http.Request, obj any) error

MustBindForm 绑定表单并验证,出错时写入 HTTP 错误响应。

func MustBindJSON

func MustBindJSON(w http.ResponseWriter, r *http.Request, obj any) error

MustBindJSON 绑定 JSON 并验证,出错时写入 HTTP 错误响应。

func MustBindQuery

func MustBindQuery(w http.ResponseWriter, r *http.Request, obj any) error

MustBindQuery 绑定 Query 参数并验证,出错时写入 HTTP 错误响应。

func MustBindURI

func MustBindURI(w http.ResponseWriter, params map[string]string, obj any) error

MustBindURI 绑定路径参数并验证,出错时写入 HTTP 错误响应。

func OkHTML

func OkHTML(w http.ResponseWriter, v string)

OkHTML 以 HTML 格式写入响应(HTTP 200)。

func OkHTMLCtx

func OkHTMLCtx(ctx context.Context, w http.ResponseWriter, v string)

OkHTMLCtx 同 OkHTML,带有 context。

func OkJSON

func OkJSON(w http.ResponseWriter, v any)

OkJSON 智能包装 v 并以 JSON 格式写入响应(HTTP 200)。

如果 v 是 *CodeError、CodeError 或 error,自动设置对应的错误码和消息; 否则设置 Code=0, Msg="ok", Data=v。

func OkJSONCtx

func OkJSONCtx(ctx context.Context, w http.ResponseWriter, v any)

OkJSONCtx 同 OkJSON,带有 context。 若 context 中含有 request_id(通过 ContextWithRequestID / WithRequestID 中间件注入), 会将其一并写入响应。

func OkXML

func OkXML(w http.ResponseWriter, v any)

OkXML 智能包装 v 并以 XML 格式写入响应(HTTP 200)。

func OkXMLCtx

func OkXMLCtx(ctx context.Context, w http.ResponseWriter, v any)

OkXMLCtx 同 OkXML,带有 context。 若 context 中含有 request_id,会将其一并写入响应。

func ParseJSON

func ParseJSON(r *http.Request, obj any) error

ParseJSON 将请求 body 解析为 JSON 到 obj 中。

func ParseJSONWithLimit

func ParseJSONWithLimit(r *http.Request, obj any, maxBytes int64) error

ParseJSONWithLimit 将请求 body 解析为 JSON,限制最大字节数。

func Redirect

func Redirect(w http.ResponseWriter, r *http.Request, url string, status int)

Redirect 以指定状态码重定向到 url。 会设置 Location 响应头,并触发浏览器跳转。

func RedirectCtx

func RedirectCtx(ctx context.Context, w http.ResponseWriter, r *http.Request, url string, status int)

RedirectCtx 同 Redirect,带有 context。

func RedirectPermanent

func RedirectPermanent(w http.ResponseWriter, r *http.Request, url string)

RedirectPermanent 永久重定向(HTTP 301 Moved Permanently)。

func RedirectPermanentCtx

func RedirectPermanentCtx(ctx context.Context, w http.ResponseWriter, r *http.Request, url string)

RedirectPermanentCtx 同 RedirectPermanent,带有 context。

func RedirectTemporary

func RedirectTemporary(w http.ResponseWriter, r *http.Request, url string)

RedirectTemporary 临时重定向(HTTP 302 Found)。

func RedirectTemporaryCtx

func RedirectTemporaryCtx(ctx context.Context, w http.ResponseWriter, r *http.Request, url string)

RedirectTemporaryCtx 同 RedirectTemporary,带有 context。

func RequestIDFromContext

func RequestIDFromContext(ctx context.Context) string

RequestIDFromContext 从 context 提取 request_id,不存在时返回空字符串。

func Validate

func Validate(obj any) error

Validate 调用全局验证器验证结构体。

func WriteHTML

func WriteHTML(w http.ResponseWriter, status int, v string)

WriteHTML 以 HTML 格式写入 HTTP 响应。

func WriteHTMLCtx

func WriteHTMLCtx(ctx context.Context, w http.ResponseWriter, status int, v string)

WriteHTMLCtx 同 WriteHTML,带有 context。

func WriteHTTPError

func WriteHTTPError(w http.ResponseWriter, status int, msg string)

WriteHTTPError 写入 HTTP 错误响应。 同时设置 HTTP 状态码和业务码为 status,用于 HTTP 层面的错误(如 400、404 等)。 等价于 WriteHTTPErrorWithCode(w, status, status, msg)。

func WriteHTTPErrorCtx

func WriteHTTPErrorCtx(ctx context.Context, w http.ResponseWriter, status int, msg string)

WriteHTTPErrorCtx 同 WriteHTTPError,带有 context。 若 context 中含有 request_id,会将其一并写入响应。 等价于 WriteHTTPErrorWithCodeCtx(ctx, w, status, status, msg)。

func WriteHTTPErrorWithCode

func WriteHTTPErrorWithCode(w http.ResponseWriter, status int, code int, msg string)

WriteHTTPErrorWithCode 写入 HTTP 错误响应,支持分离 HTTP 状态码与业务码。

在 RESTful API 中,HTTP 状态码反映传输层状态(如 400 Bad Request), 而业务码反映业务语义(如 10001 表示"用户名已存在")。 此函数允许二者独立设置,适用于需要细粒度业务错误码的场景。

用法:

// HTTP 400,业务码 10001
httpx.WriteHTTPErrorWithCode(w, http.StatusBadRequest, 10001, "username already exists")

func WriteHTTPErrorWithCodeCtx

func WriteHTTPErrorWithCodeCtx(ctx context.Context, w http.ResponseWriter, status int, code int, msg string)

WriteHTTPErrorWithCodeCtx 同 WriteHTTPErrorWithCode,带有 context。 若 context 中含有 request_id,会将其一并写入响应。

func WriteJSON

func WriteJSON(w http.ResponseWriter, status int, v any)

WriteJSON 以 JSON 格式写入 HTTP 响应。 这是一个低级函数,不会对 v 做任何包装,直接序列化写入。

func WriteJSONCtx

func WriteJSONCtx(ctx context.Context, w http.ResponseWriter, status int, v any)

WriteJSONCtx 同 WriteJSON,带有 context。

func WriteXML

func WriteXML(w http.ResponseWriter, status int, v any)

WriteXML 以 XML 格式写入 HTTP 响应。

func WriteXMLCtx

func WriteXMLCtx(ctx context.Context, w http.ResponseWriter, status int, v any)

WriteXMLCtx 同 WriteXML,带有 context。

Types

type Binding

type Binding interface {
	// Name 返回绑定器名称。
	Name() string
	// Bind 将请求数据绑定到 obj 结构体。
	Bind(*http.Request, any) error
}

Binding 描述将请求数据绑定到结构体的接口。 不同数据来源(JSON body、Query 参数、Form 表单等)实现此接口。

func Default

func Default(method, contentType string) Binding

Default 根据 HTTP 方法和 Content-Type 返回合适的绑定器。

type BindingBody

type BindingBody interface {
	Binding
	// BindBody 从字节数组绑定到 obj 结构体。
	BindBody([]byte, any) error
}

BindingBody 扩展 Binding 接口,支持从原始字节绑定。 用于 JSON、XML 等基于 body 的绑定器。

type BindingUri

type BindingUri interface {
	Name() string
	// BindUri 从路径参数 map 绑定到 obj 结构体。
	BindUri(map[string][]string, any) error
}

BindingUri 扩展接口,支持从 URI 路径参数绑定。

type CodeError

type CodeError struct {
	// Code 业务状态码。
	Code int
	// Msg 错误信息。
	Msg string
	// Cause 原始错误。
	Cause error
}

CodeError 携带业务状态码的错误。 实现 error 接口,可用于统一错误传递。

func NewCodeError

func NewCodeError(code int, msg string) *CodeError

NewCodeError 创建一个 CodeError。

func NewCodeErrorWithCause

func NewCodeErrorWithCause(code int, msg string, cause error) *CodeError

NewCodeErrorWithCause 创建一个带原始错误的 CodeError。

func (*CodeError) Error

func (e *CodeError) Error() string

Error 返回错误信息。

func (*CodeError) Unwrap

func (e *CodeError) Unwrap() error

Unwrap 返回原始错误,支持 errors.Is / errors.As。

type Group

type Group struct {
	// contains filtered or unexported fields
}

Group 是一个路由组,共享路径前缀和中间件。 支持链式调用和嵌套,便于按模块组织路由。

func (*Group) AddRoute

func (g *Group) AddRoute(r Route, opts ...RouteOption)

AddRoute 添加单个路由到路由组,可附加 RouteOption。 opts 中的 RouteOption 会追加在组前缀、组中间件之后应用。

func (*Group) AddRoutes

func (g *Group) AddRoutes(rs []Route, opts ...RouteOption)

AddRoutes 添加多个路由到路由组,可附加 RouteOption。 路由路径会自动拼接组前缀,handler 会应用组中间件。 opts 中的 RouteOption 会追加在组前缀、组中间件之后应用。

func (*Group) Group

func (g *Group) Group(prefix string, mws ...Middleware) *Group

Group 创建子路由组,继承父组的前缀和中间件。

api := server.Group("/api", logMiddleware)
v1 := api.Group("/v1", authMiddleware)
// 路由前缀 /api/v1,中间件 logMiddleware → authMiddleware

func (*Group) Use

func (g *Group) Use(mws ...Middleware)

Use 添加中间件到路由组。

type Middleware

type Middleware func(http.HandlerFunc) http.HandlerFunc

Middleware 是 HTTP 中间件函数。 接收下游 handler,返回包装后的 handler。

约定:中间件调用 next(w, r) 将请求传递给下游,不调用则中断链路。

func Logging(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        next(w, r)
        log.Printf("%s %s %v", r.Method, r.URL.Path, time.Since(start))
    }
}

func WithBreaker

func WithBreaker() Middleware

WithBreaker 返回一个熔断中间件,保护下游 handler 不被级联拖垮。 基于 breaker 模块的 Google SRE 算法,熔断器以 "METHOD://path" 为名,按路由隔离。

熔断打开时返回 503 Service Unavailable;请求成功(<500)上报 Accept, 请求失败(>=500)上报 Reject,用于驱动熔断状态。

server.Use(httpx.WithBreaker())

func WithContentSecurity

func WithContentSecurity(key []byte, tolerance time.Duration) Middleware

WithContentSecurity 返回一个内容安全校验中间件(防篡改 + 防重放)。 客户端需在 `X-Content-Security` 头携带签名:

X-Content-Security: time=<unix秒>; signature=<base64 HMAC-SHA256>

签名内容为:`timestamp\nmethod\npath\nquery\nbodySha256Hex` (timestamp 为请求头中的时间戳,bodySha256Hex 为请求体的 SHA-256 十六进制摘要)。

校验规则:

  • 签名有效(HMAC-SHA256 匹配)且时间戳在 tolerance 容差内 → 放行
  • 签名无效 → 返回 401
  • 时间戳超出容差(防重放)→ 返回 403

key 为双方共享的 HMAC 密钥。

server.Use(httpx.WithContentSecurity([]byte("shared-secret"), 5*time.Minute))

func WithCors

func WithCors(allowOrigins ...string) Middleware

WithCors 返回一个为响应设置 CORS 头的中间件。

allowOrigins 为允许的来源列表;传入 "*" 表示允许所有来源。 同源请求(Origin 与 Host 一致)不设置 CORS 头; 未授权来源返回 403;OPTIONS 预检请求返回 204。

func WithCryption

func WithCryption(key []byte) Middleware

WithCryption 返回一个 AES-GCM 请求/响应加密中间件。 请求体需为 base64 编码的 AES-GCM 密文(nonce || ciphertext), 中间件解密后交给 handler;handler 写入的响应会被加密后返回给客户端。

采用 AES-GCM 认证加密(AEAD),同时保证机密性与完整性(防篡改), nonce 每次随机生成;相比常见的 AES-ECB 等非认证模式,GCM 能抵御 篡改与重放,安全性更高。

响应超过 1MB 时自动回退为明文输出(不加密),避免大响应导致 OOM。

密钥 key 长度必须为 16/24/32 字节(对应 AES-128/192/256)。

server.Use(httpx.WithCryption([]byte("0123456789abcdef")))

func WithGunzip

func WithGunzip() Middleware

WithGunzip 返回一个自动解压 gzip 请求体的中间件。 请求头 Content-Encoding 含 "gzip" 时,将请求体包装为 gzip 读取器。 解压失败返回 400 Bad Request。

server.Use(httpx.WithGunzip())

func WithLogger

func WithLogger() Middleware

WithLogger 返回一个请求日志中间件。 记录每个请求的方法、路径、状态码、响应字节数和耗时。 配合 trace 包使用时,logger 的 Ctx 提取器会自动带上 trace_id/span_id。

server.Use(httpx.WithLogger())

func WithMaxBytes

func WithMaxBytes(n int64) Middleware

WithMaxBytes 返回一个限制请求体大小的中间件。 请求体 Content-Length 超过 n 字节时直接返回 413 Request Entity Too Large。 对分块传输(无 Content-Length)的请求,用 http.MaxBytesReader 在读取时限制。

n <= 0 表示不限制。

server.Use(httpx.WithMaxBytes(1 << 20)) // 限制 1MB

func WithMaxConns

func WithMaxConns(n int) Middleware

WithMaxConns 返回一个限制同时处理请求数的中间件。 并发数超过 n 时直接返回 503 Service Unavailable,防止连接耗尽。

n <= 0 表示不限制。

server.Use(httpx.WithMaxConns(1000))

func WithRecovery

func WithRecovery() Middleware

WithRecovery 返回一个 panic 恢复中间件。 捕获 handler 中的 panic,记录堆栈并返回 500,防止进程崩溃。

server.Use(httpx.WithRecovery())

func WithRequestID

func WithRequestID() Middleware

WithRequestID 返回一个 request_id 中间件。 从 X-Request-Id 请求头读取,不存在则自动生成(google/uuid), 注入 context 并回写响应头 X-Request-Id。

server.Use(httpx.WithRequestID())

配合 OkJSONCtx / OkXMLCtx / WriteHTTPErrorCtx 使用,request_id 会自动出现在响应中。

func WithRouteBreaker

func WithRouteBreaker() Middleware

WithRouteBreaker 返回一个按路由隔离的熔断中间件。 每个路由(METHOD:path)拥有独立的熔断器,统计互不影响, 避免单个路由的失败拉低其他路由的通过率。

熔断器通过 breaker.GetBreaker 按名称缓存,同名路由共享同一实例。 熔断打开时返回 503 Service Unavailable;请求成功(<500)上报 Accept, 请求失败(>=500)上报 Reject。

server.Use(httpx.WithRouteBreaker())

func WithShedding

func WithShedding() Middleware

WithShedding 返回一个自适应降载中间件。 基于滑动窗口统计吞吐与延迟,动态估算系统承载上限, 过载时按概率丢弃请求(返回 503),保护服务不被流量洪峰压垮。

与限流(ratelimit)的区别:

  • 限流是静态配额,保护下游;

  • 降载是自适应保护自身,仅在系统过载时触发。

    server.Use(httpx.WithShedding())

func WithTimeout

func WithTimeout(duration time.Duration) Middleware

WithTimeout 返回一个请求超时中间件。 每个请求最多执行 duration,超时返回 503 Service Unavailable。 客户端主动断开返回 499;WebSocket / SSE 请求不受超时限制。

duration <= 0 时中间件不生效(直接放行)。

server.Use(httpx.WithTimeout(5 * time.Second))

type Response

type Response[T any] struct {
	// Code 业务状态码,0 表示成功。
	Code int `json:"code" xml:"code"`
	// Msg 提示信息。
	Msg string `json:"msg" xml:"msg"`
	// Data 响应数据。
	Data T `json:"data,omitempty" xml:"data,omitempty"`
	// RequestID 请求 ID(可选),从 context 提取,无则省略。
	RequestID string `json:"request_id,omitempty" xml:"request_id,omitempty"`
}

Response 统一响应结构,data 字段使用泛型支持任意类型。

用法:

type User struct { Name string `json:"name"` }
resp := httpx.Response[User]{
    Code: httpx.CodeOK,
    Msg:  httpx.MsgOK,
    Data: User{Name: "Alice"},
}

type Route

type Route struct {
	Method  string
	Path    string
	Handler http.HandlerFunc
}

Route 表示一个 HTTP 路由。

func ApplyMiddleware

func ApplyMiddleware(mw Middleware, rs ...Route) []Route

ApplyMiddleware 将中间件应用到路由,返回包装后的路由。 适用于需要在添加路由前对特定路由包装中间件的场景。

server.AddRoutes(httpx.ApplyMiddleware(authMiddleware,
    httpx.Route{Method: "GET", Path: "/profile", Handler: getProfile},
    httpx.Route{Method: "PUT", Path: "/profile", Handler: updateProfile},
))

func ApplyMiddlewares

func ApplyMiddlewares(mws []Middleware, rs ...Route) []Route

ApplyMiddlewares 将多个中间件应用到路由,返回包装后的路由。 中间件按切片顺序执行(第一个先执行)。

func PprofRoutes

func PprofRoutes(prefix string) []Route

PprofRoutes 返回标准 pprof 性能分析路由列表,不会自动注册到 Server。

prefix 指定路由前缀,为空时默认使用 /debug/pprof。 返回的路由需通过 Server.AddRoutes 手动注册,可附加 RouteOption(如中间件)。

// 默认前缀 /debug/pprof
server.AddRoutes(httpx.PprofRoutes(""))

// 自定义前缀
server.AddRoutes(httpx.PprofRoutes("/admin/pprof"))

// 带认证中间件(生产环境推荐)
server.AddRoutes(httpx.PprofRoutes(""), httpx.WithMiddleware(authMiddleware))

返回的路由列表(共 11 条):

  • GET {prefix}/ — 索引页,列出所有可用的 profile
  • GET {prefix}/cmdline — 当前进程的命令行参数
  • GET {prefix}/profile — CPU 性能分析(通过 seconds 参数指定采样时长)
  • GET {prefix}/symbol — 符号表查询
  • GET {prefix}/trace — 执行追踪(通过 seconds 参数指定采样时长)
  • GET {prefix}/allocs — 所有内存分配样本
  • GET {prefix}/block — 阻塞操作堆栈(需先调用 runtime.SetBlockProfileRate)
  • GET {prefix}/goroutine — 当前 goroutine 堆栈
  • GET {prefix}/heap — 堆内存分配
  • GET {prefix}/mutex — 互斥锁竞争(需先调用 runtime.SetMutexProfileFraction)
  • GET {prefix}/threadcreate — OS 线程创建

注意:pprof.Index 处理器内部硬编码了 /debug/pprof/ 路径前缀, 使用默认前缀时索引页和子路径完全正常;使用自定义前缀时各 profile 端点仍可正常访问, 但索引页内链接仍指向 /debug/pprof/ 路径。

安全提示:pprof 端点会暴露程序内部信息,生产环境应通过中间件进行访问控制。

type RouteOption

type RouteOption func(*routeGroup)

RouteOption 用于自定义一组路由的选项,如前缀、中间件。

func WithMiddleware

func WithMiddleware(mw Middleware) RouteOption

WithMiddleware 为路由组添加一个中间件。 中间件按添加顺序执行(先添加的先执行)。

func WithMiddlewares

func WithMiddlewares(mws ...Middleware) RouteOption

WithMiddlewares 为路由组添加多个中间件。 中间件按传入顺序执行(第一个先执行)。

func WithPrefix

func WithPrefix(prefix string) RouteOption

WithPrefix 为路由组添加路径前缀。

server.AddRoutes([]Route{
    {Method: "GET", Path: "/users", Handler: listUsers},
    {Method: "POST", Path: "/users", Handler: createUser},
}, httpx.WithPrefix("/api/v1"))

注册的路由为:GET /api/v1/users, POST /api/v1/users

type RunOption

type RunOption func(*Server)

RunOption 用于自定义 Server 的选项,如超时、TLS。 也可直接传入闭包,在构造时注册路由、添加中间件等:

server := httpx.NewServer(conf, func(s *httpx.Server) {
    s.Use(loggingMiddleware)
    s.AddRoute(httpx.Route{Method: "GET", Path: "/ping", Handler: ping})
})

func WithIdleTimeout

func WithIdleTimeout(d time.Duration) RunOption

WithIdleTimeout 设置空闲连接超时。覆盖配置中的 IdleTimeout。

func WithMaxHeaderBytes

func WithMaxHeaderBytes(n int) RunOption

WithMaxHeaderBytes 设置最大请求头字节数。覆盖配置中的 MaxHeaderBytes。

func WithReadTimeout

func WithReadTimeout(d time.Duration) RunOption

WithReadTimeout 设置读超时。覆盖配置中的 ReadTimeout。

func WithShutdownTimeout

func WithShutdownTimeout(d time.Duration) RunOption

WithShutdownTimeout 设置优雅关闭超时时间,覆盖配置中的 ShutdownTimeout。

func WithTLSConfig

func WithTLSConfig(cfg *tls.Config) RunOption

WithTLSConfig 设置 TLS 配置。

func WithWriteTimeout

func WithWriteTimeout(d time.Duration) RunOption

WithWriteTimeout 设置写超时。覆盖配置中的 WriteTimeout。

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server 是一个 HTTP 服务器,支持路由注册、中间件和优雅关闭。

底层使用 http.ServeMux,原生支持:

  • 方法匹配(GET / POST / PUT ...),自动返回 405 Method Not Allowed
  • 路径参数(/users/{id}),通过 r.PathValue("id") 获取
  • 通配路径(/files/{path...}),通过 r.PathValue("path") 获取
  • 自动 404 Not Found

func NewServer

func NewServer(conf ServerConfig, opts ...RunOption) *Server

NewServer 创建一个 HTTP 服务器。

conf := httpx.ServerConfig{
    Host: "0.0.0.0",
    Port: 8080,
}
server := httpx.NewServer(conf, httpx.WithReadTimeout(30*time.Second))

func (*Server) AddRoute

func (s *Server) AddRoute(r Route, opts ...RouteOption)

AddRoute 添加单个路由,可附加 RouteOption。

func (*Server) AddRoutes

func (s *Server) AddRoutes(rs []Route, opts ...RouteOption)

AddRoutes 添加一组路由。

opts 中的 RouteOption 会统一应用到这组路由(如前缀、中间件)。

中间件执行顺序:全局中间件(Use 添加)→ 组中间件(WithMiddleware 添加)→ 路由 handler。

func (*Server) Group

func (s *Server) Group(prefix string, mws ...Middleware) *Group

Group 创建一个路由组。

api := server.Group("/api/v1")
api.AddRoute(httpx.Route{Method: "GET", Path: "/users", Handler: listUsers})

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler 返回服务器的 HTTP Handler,可用于 httptest 等场景。 返回的 handler 已应用全局中间件(Use 添加)。 并发安全:懒加载构建受内部锁保护。

func (*Server) Mux

func (s *Server) Mux() *http.ServeMux

Mux 返回底层的 ServeMux,用于高级场景(如手动注册路由)。

func (*Server) PrintRoutes

func (s *Server) PrintRoutes()

PrintRoutes 打印已注册的路由列表。

server.PrintRoutes()
// 输出:
// DELETE  /admin/users/{id}   --> main.deleteUser
// GET     /api/v1/users       --> main.listUsers
// GET     /api/v1/users/{id}   --> main.getUser
// GET     /health             --> main.health
// POST    /api/v1/users       --> main.createUser
//
// 5 routes registered

func (*Server) Routes

func (s *Server) Routes() []Route

Routes 返回已注册的所有路由(已应用中间件)。 返回的是副本,修改不会影响 Server 内部状态。

func (*Server) SetNotFoundHandler

func (s *Server) SetNotFoundHandler(h http.HandlerFunc)

SetNotFoundHandler 设置路由未找到(404)时的自定义响应处理器。 所有未被任何路由匹配的请求都会交给该处理器,替代默认的 "404 page not found"。

server.SetNotFoundHandler(func(w http.ResponseWriter, r *http.Request) {
    httpx.OkJSON(w, httpx.NewCodeError(httpx.CodeNotFound, "resource not found"))
})

func (*Server) Shutdown

func (s *Server) Shutdown() error

Shutdown 优雅关闭服务器,等待活跃连接处理完毕。 超时时间由 WithShutdownTimeout 设置(默认 10 秒)。 关闭失败时记录日志但不静默吞掉错误。

func (*Server) Start

func (s *Server) Start() error

Start 启动 HTTP 服务器,支持优雅关闭。

服务器在独立 goroutine 中运行,主 goroutine 阻塞等待信号。 收到 SIGINT(Ctrl+C)、SIGTERM 或 SIGHUP 时执行优雅关闭。

如果配置了 CertFile 和 KeyFile,则启动 HTTPS 服务。

func (*Server) Use

func (s *Server) Use(mws ...Middleware)

Use 添加全局中间件,对所有已注册和后续注册的路由生效。 多个中间件按添加顺序执行(先添加的先执行)。

全局中间件在请求时动态应用(包装整个路由器),因此即使先注册路由、 再调用 Use,已注册的路由也会经过新添加的全局中间件。 注意:Start 启动后再调用 Use 不会影响已经运行的 httpServer。

type ServerConfig

type ServerConfig struct {
	// Host 监听地址,默认 "0.0.0.0"。
	Host string `json:",default=0.0.0.0"`
	// Port 监听端口,默认 8080。
	Port int `json:",default=8080,range=[1:65535]"`
	// CertFile TLS 证书文件路径(可选,设置后启用 HTTPS)。
	CertFile string `json:",optional"`
	// KeyFile TLS 私钥文件路径(可选)。
	KeyFile string `json:",optional"`
	// ReadTimeout 读超时,默认 10s。
	// 通过 ServerConfig 设 0 会被当作“未设置”而使用默认值;
	// 若需设为 0(不限制),请用 WithReadTimeout(0)。
	ReadTimeout time.Duration `json:",default=10s"`
	// WriteTimeout 写超时,默认 10s。
	// 通过 ServerConfig 设 0 会被当作“未设置”而使用默认值;
	// 若需设为 0(不限制),请用 WithWriteTimeout(0)。
	WriteTimeout time.Duration `json:",default=10s"`
	// IdleTimeout 空闲连接超时,默认 120s。
	// 通过 ServerConfig 设 0 会被当作“未设置”而使用默认值;
	// 若需设为 0(不限制),请用 WithIdleTimeout(0)。
	IdleTimeout time.Duration `json:",default=120s"`
	// MaxHeaderBytes 最大请求头字节数,默认 1MB。
	MaxHeaderBytes int `json:",default=1048576"`
	// ShutdownTimeout 优雅关闭超时时间,默认 10s。
	// 通过 ServerConfig 设 0 会被当作“未设置”而使用默认值;
	// 若需设为 0,请用 WithShutdownTimeout(0)。
	ShutdownTimeout time.Duration `json:",default=10s"`
}

ServerConfig 是 HTTP 服务器配置。 使用 json 标签声明默认值和约束,兼容 conf 包从配置文件加载。

type StructValidator

type StructValidator interface {
	// ValidateStruct 验证结构体,验证通过返回 nil。
	ValidateStruct(any) error
	// Engine 返回底层的验证引擎。
	Engine() any
}

StructValidator 结构体验证接口。

var Validator StructValidator = &defaultValidator{}

Validator 全局验证器实例。

Jump to

Keyboard shortcuts

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