Documentation
¶
Overview ¶
Package contract 框架核心契约:统一 Handler 模板、路由注册描述与基础类型。 业务层(app/handlers)通过别名引用本包类型,运行时(internal/server)与 文档生成(internal/openapi)通过本包消费路由注册表。
Index ¶
- Variables
- func BadRequest(msg string) error
- func BindFail(status int) (int, int)
- func CheckHandler(fn any) error
- func CheckTarget(t reflect.Type, v reflect.Value) any
- func Conflict(msg string) error
- func DefaultErrorMapper(err error) (httpStatus, bizCode int)
- func Forbidden(msg string) error
- func Framework(ctx context.Context) any
- func FuncName(fn any) string
- func HasParamBinder(t reflect.Type) bool
- func Internal(msg string) error
- func IsBodyMethod(method string) bool
- func NewStatusError(status int, msg string) error
- func NewValue(t reflect.Type) reflect.Value
- func NotFound(msg string) error
- func RegisterParamBinder[T any](fn func(src []string) (T, error))
- func ResolveError(mapError func(err error) (httpStatus, bizCode int), err error) (int, int, string)
- func ResolveErrorStatus(err error) (status, code int, msg string, ok bool)
- func SetRaw(f reflect.Value, raw, name string) error
- func SetRawBasic(f reflect.Value, raw, name string) error
- func SetSliceValue(f reflect.Value, vals []string, name string) error
- func TagValue(ft reflect.StructField, key string) (string, bool)
- func TransformIn(ctx context.Context, v any) error
- func TransformOut(ctx context.Context, v reflect.Value) (reflect.Value, error)
- func Unauthorized(msg string) error
- func WithCause(statusErr error, cause error) error
- func WithFramework(ctx context.Context, fw any) context.Context
- type AdaptHandler
- type Empty
- type FieldMeta
- type FileStream
- type Group
- type InTransformer
- type NoReq
- type OutTransformer
- type ParamBinder
- type Response
- type ResponseWrapper
- type Route
- type RouteMeta
- type Server
- type StatusCoder
- type StatusError
Constants ¶
This section is empty.
Variables ¶
var ErrNotFound = errors.New("not found")
ErrNotFound 资源不存在(运行时适配器映射为 HTTP 404)。 需要携带对外信息时优先使用 contract.NotFound(msg)(StatusError)。
Functions ¶
func BindFail ¶
BindFail 绑定/校验失败响应的 (status, code):默认 200 + CodeError(存量行为); 自定义非 200 状态码时 code 跟随状态码(与 StatusError 约定一致)。
func CheckHandler ¶
CheckHandler 校验 Handler 是否符合统一模板 func(context.Context, Q, B) (R, error)。 适配器与文档生成器在挂载/生成期调用:签名错误尽早暴露并给出可读信息, 避免拖到反射调用期才 panic 且信息晦涩。
func CheckTarget ¶
CheckTarget 校验入参目标:接口类型占位(NoReq/any 等)返回 nil(validator.isNil 跳过); 具体结构体返回其指针(与绑定阶段一致)
func DefaultErrorMapper ¶
DefaultErrorMapper 默认兑底映射:ErrNotFound → 404;其余业务错误 → HTTP 200 + code=7。
func HasParamBinder ¶
HasParamBinder 判断类型是否注册过自定义参数绑定器。 openapi 生成器据此把参数 schema 标注为 string——绑定器类型的 HTTP 形态是原始字符串 (逗号串、ID 等),而非其 Go 类型的 JSON 形态。
func IsBodyMethod ¶
func NewStatusError ¶
NewStatusError 构造携带自定义状态码的错误
func RegisterParamBinder ¶
RegisterParamBinder 注册某字段类型的自定义绑定器。 T 为字段声明类型(如 IDs、*User);同名类型重复注册覆盖。
func ResolveError ¶
ResolveError 业务错误解析:错误自带状态码优先,否则调用 mapError 兑底 (mapError 由适配器注入,Server.SetErrorMapper;传 nil 则用 DefaultErrorMapper)。
func ResolveErrorStatus ¶
ResolveErrorStatus 提取错误自带的状态信息(StatusError → StatusCoder)。 ok=false 表示普通错误,由调用方决定兑底策略(业务错误走 errorMapper,绑定错误走 bindStatus)。
func SetRaw ¶
把原始字符串解析写入字段(query/path/header 共用)。 支持基本类型、指针(自动分配)、time.Time(RFC3339)与切片(逗号分隔或重复参数); 声明了绑定标签但类型不支持时返回错误(避免静默丢值难以排查)。
func SetSliceValue ¶
绑定切片字段:vals 为收集到的原始值(重复参数或逗号分隔展开后)。 []string 保持原样;其他元素类型逐个解析,失败即报错。
func TransformIn ¶
TransformIn 入参转换(适配器内部使用):v 为绑定后的入参(*Q / *B 指针)。
func TransformOut ¶
TransformOut 出参转换(适配器内部使用):v 为 Handler 返回的响应值 (reflect.Call 的返回值,值类型可能不可寻址)。 返回转换后的值;指针接收者实现且为值类型时,写回拷贝。
Types ¶
type AdaptHandler ¶
AdaptHandler 统一 Handler 模板:
func(ctx context.Context, query Q, body B) (resp R, err error)
type FieldMeta ¶
type FieldMeta struct {
Index int
Kind reflect.Kind
Path string
Query string
Form string
Header string
Def string // default 标签:绑定缺失时的运行时默认值(与文档 default 同步生效)
Children []FieldMeta // 内嵌结构体递归展平
}
FieldMeta 绑定字段元数据(挂载期解析一次,请求期零反射)。 与框架无关:path/query/form/header/default 标签由各框架适配器按同一语义消费, 框架侧只保留"从请求取原始值"的取值函数(如 gin 的 c.Query / echo 的 c.QueryParam)。
func ParseFields ¶
ParseFields 反射解析结构体字段元数据(内嵌结构体递归展平)。 挂载期调用一次即缓存;各框架适配器共享同一份解析结果。
type FileStream ¶
type FileStream struct {
Name string // 下载文件名(Content-Disposition)
Size int64 // 内容长度
ContentType string // 如 application/octet-stream、text/plain
Reader io.Reader
}
FileStream 二进制下载响应。运行时适配器识别该类型后直接输出流, 数据源可以是文件、go:embed 内存数据或任何 io.Reader(见 app/handlers/file.go 示例)。
type Group ¶
type Group struct {
Prefix string
Description string
Tags []string
Middlewares []any // 框架中间件函数;名字由反射派生(见 FuncName),文档侧按名匹配钩子
Routes []Route
Children []*Group
}
Group 路由分组(树形):对应 gin.RouterGroup / echo.Group 的嵌套模型。
- Prefix 为空表示根组
- 组内 Route.Path 为相对组前缀的路径(列表路由用 "" 表示组根)
- Middlewares 沿树向子组继承(运行时与文档生成行为一致)
- 文档侧 Tags 合并:组 Tags + 路由 Tags
type InTransformer ¶
InTransformer 入参转换接口:Q/B 绑定完成后、校验之前被适配器自动调用。 用于规范化输入(trim、大小写归一、默认值填充);返回错误将短路请求。
实现建议使用指针接收者(与 B 的绑定值一致,修改直接生效):
func (r *CreateUserReq) InTransform(ctx context.Context) error {
r.Name = strings.TrimSpace(r.Name)
return nil
}
type OutTransformer ¶
OutTransformer 出参转换接口:Handler 返回后、序列化之前被适配器自动调用。 用于输出加工(脱敏、裁剪字段、补充计算字段);返回错误将短路请求。
建议使用指针接收者;值接收者也可用(只读场景),但修改不会写回:
func (u *User) OutTransform(ctx context.Context) error {
u.Password = "******"
return nil
}
type ParamBinder ¶
ParamBinder 把 query/path/header 的原始字符串解析为字段值。 src:原始值列表(单值参数长度 1;重复参数 ?ids=1&ids=2 与逗号串由实现自行处理)。 返回值必须可赋给字段声明类型;错误建议使用 StatusError(如 NotFound/BadRequest), 会汇入统一错误链(HTTP 状态码 + 响应壳)。
注册方式(通常在 init 或装配阶段):
contract.RegisterParamBinder(func(src []string) (IDs, error) { ... })
type Response ¶
Response 响应定制壳:业务层返回 contract.Response[R] 时, 适配器应用 Status/Headers/Cookies 后,Data 仍走统一 envelope {code, data, msg}。 例:return contract.Response[handlers.User]{Status: 201, Headers: ..., Data: u}, nil
func (Response[R]) ResponseCookies ¶
func (Response[R]) ResponseData ¶
func (Response[R]) ResponseHeaders ¶
func (Response[R]) ResponseStatus ¶
type ResponseWrapper ¶
type ResponseWrapper interface {
ResponseStatus() int
ResponseHeaders() map[string]string
ResponseCookies() []*http.Cookie
ResponseData() any
}
ResponseWrapper 适配器识别接口:泛型实例通过该接口被统一处理
type Route ¶
type Route struct {
Method string
Path string
Summary string
Description string
Tags []string
DefaultStatusCode int
Deprecated bool
Envelope response.Envelope
Handler any // func(context.Context, Q, B) (R, error)
}
Route 路由表条目(非泛型;Handler 由适配器通过反射消费,Q/B/R 泛型信息由 New 在构造期保证)
type RouteMeta ¶
type RouteMeta[Q, B, R any] struct { Method string Path string Summary string Description string Tags []string // DefaultStatusCode 成功响应默认 HTTP 状态码;0 → 200。 // 动态覆盖优先级:contract.Response[R].Status > DefaultStatusCode > 200。 // OpenAPI 文档生成器读取该值作为成功响应码(替代硬编码 200)。 DefaultStatusCode int // Deprecated 弃用标记(运行时+文档共用层): // 文档生成 op.Deprecated=true;运行时后续可在 dev 模式对弃用接口打日志。 Deprecated bool // Envelope 路由级响应壳;nil → 服务级默认壳(server.SetEnvelope)。 // 文档侧壳 schema 用 openapi.OptionWithEnvelopeSchema 配对配置。 Envelope response.Envelope Handler AdaptHandler[Q, B, R] }
RouteMeta 路由注册描述(强类型)。 鉴权等中间件效果不在本结构声明:中间件挂载在所属 Group(见 Group.Middlewares), 文档标注由 internal/openapi 按中间件函数名匹配文档钩子(RegisterMiddlewareDoc)。
type Server ¶
Server 运行时适配器接口规范:各框架适配器(servergin / serverecho) 提供具体实现,业务装配层面向该接口编程时可互换适配器。 作为 server 实现的示范存在:适配器可参考其形态提供自己的 Mount 签名。
type StatusCoder ¶
StatusCoder 最小契约:任何错误实现该接口即可携带 HTTP 状态码。 适配器错误路径按优先级识别:StatusError → StatusCoder → SetErrorMapper 全局映射
type StatusError ¶
StatusError 携带状态码/业务码/对外信息的错误。 业务层直接返回:return nil, contract.NotFound("用户不存在")
字段规则:
- Status:HTTP 状态码;0 视为未设置,StatusCode() 兜底 500
- Code:业务码;0 视为未设置,适配器沿用默认约定 (HTTP 200 → 默认业务错误码;非 200 → 跟随状态码,与现有 ErrNotFound 映射一致)
- Msg:对外错误信息;空则回退 err.Error()
- Err:内部错误(不对外暴露),支持 errors.Unwrap 链路穿透
func (*StatusError) Error ¶
func (e *StatusError) Error() string
func (*StatusError) StatusCode ¶
func (e *StatusError) StatusCode() int
StatusCode 实现 StatusCoder;0 → 500
func (*StatusError) Unwrap ¶
func (e *StatusError) Unwrap() error
Unwrap 支持错误链穿透(fmt.Errorf("...: %w", err) 后仍可被 errors.As 识别)