Documentation
¶
Overview ¶
Package core 提供 tingo 的运行时内核。
设计原则:
- 零成本抽象 —— 类型定义零拷贝,指针转换是编译期 no-op。
- 零额外分配 —— 不在请求路径上包装、不逃逸、不反射。
- 注册期展开 —— 多应用/中间件在启动时全部展开进路由树。
Package core 提供 tingo 的运行时内核。
设计原则:
- 零成本抽象 —— 类型定义零拷贝,指针转换是编译期 no-op。
- 零额外分配 —— 不在请求路径上包装、不逃逸、不反射。
- 注册期展开 —— 多应用/中间件在启动时全部展开进路由树。
driver 提供类型安全的驱动注册和实例管理。
Index ¶
- Variables
- func Apps(r Router, cfg *AppConfig, apps ...Application)
- func Bind[T any](c *Container, factory func(*Container) (T, error))
- func BindFrameworkApp(c *Ctx, app *App)
- func BindInterface[I any, T any](c *Container, factory func(*Container) (T, error))
- func BindNamed[T any](c *Container, name string, factory func(*Container) (T, error))
- func BindNamedTransient[T any](c *Container, name string, factory func(*Container) (T, error))
- func BindNamedValue[T any](c *Container, name string, v T)
- func BindTransient[T any](c *Container, factory func(*Container) (T, error))
- func BindValue[T any](c *Container, v T)
- func DefaultApps(r Router, cfg PageConfig, apps ...Application)
- func GinChain(hs []Handler) gin.HandlersChain
- func GinOf(h Handler) gin.HandlerFunc
- func Has[T any](c *Container) bool
- func HasNamed[T any](c *Container, name string) bool
- func MustConfigureApplication(r Router, cfg *AppConfig, apps ...Application)
- func MustConfigureApps(r Router, cfg PageConfig, apps ...Application)
- func MustResolve[T any](c *Container) T
- func MustResolveNamed[T any](c *Container, name string) T
- func RegisterApp(name string, app Application)
- func RegisterMeta(method, fullPath string, meta *RouteMeta)
- func ResetApps()
- func ResetMeta()
- func Resolve[T any](c *Container) (T, error)
- func ResolveNamed[T any](c *Container, name string) (T, error)
- func SetResponder(r Responder)
- func ToGin(c *Ctx) *gin.Context
- func ValidateStruct(obj any) error
- type App
- func (a *App) ApplicationNames() []string
- func (a *App) Applications() []AppInfo
- func (a *App) Boot(ctx context.Context) error
- func (a *App) ConfigureApplication(name string, config AppConfig) error
- func (a *App) Container() *Container
- func (a *App) HasService(name string) bool
- func (a *App) LookupApplication(name string) (AppInfo, bool)
- func (a *App) MountApplication(r Router, app Application, cfg *AppConfig) Router
- func (a *App) Register(services ...Service) error
- func (a *App) RegisterApplication(name string, app Application)
- func (a *App) RegisterRouteMeta(method, fullPath string, meta *RouteMeta)
- func (a *App) Shutdown(ctx context.Context) error
- func (a *App) Start() error
- func (a *App) State() State
- type AppBooter
- type AppConfig
- type AppConfigurer
- type AppInfo
- type AppMiddlewarer
- type Application
- type Container
- type Ctx
- func (c *Ctx) Abort()
- func (c *Ctx) AbortWithStatus(code int)
- func (c *Ctx) Action() string
- func (c *Ctx) App() string
- func (c *Ctx) Bind(obj any) error
- func (c *Ctx) BindAll(obj any) error
- func (c *Ctx) BindAllAndValidate(obj any) error
- func (c *Ctx) BindHeader(obj any) error
- func (c *Ctx) BindJSON(obj any) error
- func (c *Ctx) BindQuery(obj any) error
- func (c *Ctx) BindURI(obj any) error
- func (c *Ctx) Body() ([]byte, error)
- func (c *Ctx) ContentType() string
- func (c *Ctx) Controller() string
- func (c *Ctx) Cookie(name string) string
- func (c *Ctx) Data(code int, contentType string, data []byte)
- func (c *Ctx) Deadline() (time.Time, bool)
- func (c *Ctx) DefaultPost(key, def string) string
- func (c *Ctx) DefaultQuery(key, def string) string
- func (c *Ctx) Done() <-chan struct{}
- func (c *Ctx) Download(filepath, filename string)
- func (c *Ctx) Err() error
- func (c *Ctx) File(name string) (*multipart.FileHeader, error)
- func (c *Ctx) Files(name string) ([]*multipart.FileHeader, error)
- func (c *Ctx) Framework() *App
- func (c *Ctx) FullPath() string
- func (c *Ctx) G() *gin.Context
- func (c *Ctx) Get(key string) (any, bool)
- func (c *Ctx) GetBool(key string) bool
- func (c *Ctx) GetInt(key string) int
- func (c *Ctx) GetInt64(key string) int64
- func (c *Ctx) GetString(key string) string
- func (c *Ctx) HTML(name string, data any)
- func (c *Ctx) Header(key string) string
- func (c *Ctx) Hijack() (net.Conn, error)
- func (c *Ctx) Host() string
- func (c *Ctx) IP() string
- func (c *Ctx) IsAborted() bool
- func (c *Ctx) IsAjax() bool
- func (c *Ctx) JSON(v any)
- func (c *Ctx) JSONStatus(code int, v any)
- func (c *Ctx) Method() string
- func (c *Ctx) MustGet(key string) any
- func (c *Ctx) Next()
- func (c *Ctx) NoContent()
- func (c *Ctx) Param(key string) string
- func (c *Ctx) Path() string
- func (c *Ctx) Post(key string) string
- func (c *Ctx) PostArray(key string) []string
- func (c *Ctx) PostMap(key string) map[string]string
- func (c *Ctx) Query(key string) string
- func (c *Ctx) QueryArray(key string) []string
- func (c *Ctx) QueryMap(key string) map[string]string
- func (c *Ctx) RawQuery() string
- func (c *Ctx) Redirect(code int, location string)
- func (c *Ctx) Referer() string
- func (c *Ctx) RemoteIP() string
- func (c *Ctx) Req() *http.Request
- func (c *Ctx) RequestID() string
- func (c *Ctx) Res() gin.ResponseWriter
- func (c *Ctx) Route() *RouteMeta
- func (c *Ctx) SSE(event string, data any)
- func (c *Ctx) SaveFile(f *multipart.FileHeader, dst string) error
- func (c *Ctx) Scheme() string
- func (c *Ctx) ServeFile(filepath string)
- func (c *Ctx) Set(key string, val any)
- func (c *Ctx) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) *Ctx
- func (c *Ctx) SetHeader(key, val string) *Ctx
- func (c *Ctx) SetRequestID(id string)
- func (c *Ctx) Status(code int) *Ctx
- func (c *Ctx) Stream(step func(w io.Writer) bool) bool
- func (c *Ctx) String(format string, values ...any)
- func (c *Ctx) StringStatus(code int, format string, values ...any)
- func (c *Ctx) URL() *url.URL
- func (c *Ctx) UserAgent() string
- func (c *Ctx) Value(key any) any
- func (c *Ctx) XML(v any)
- func (c *Ctx) YAML(v any)
- type CtxKey
- type DriverFactory
- type DriverManager
- type DriverManagerConfig
- type DriverRegistry
- type Handler
- type HandlerE
- type Middleware
- type PageConfig
- type Responder
- type RouteMeta
- type Router
- type Service
- type State
- type WeightedMiddleware
Constants ¶
This section is empty.
Variables ¶
var AppConfigProvider func(name string, base AppConfig) AppConfig
AppConfigProvider 由上层(如 frame/t)注入,用于根据框架配置动态解析每个应用的 AppConfig(多应用路由:default_app/app_map/domain_bind/deny_app)。 接收应用名与注册期的基础配置,返回最终生效的配置。在引擎 Boot 阶段(配置已加载)调用。 未注入则直接使用注册期设定的 AppConfig。
var ErrNotHijackable = errors.New("tingo: response writer does not support hijacking")
ErrNotHijackable 底层 ResponseWriter 不支持连接接管。
Functions ¶
func Apps ¶
func Apps(r Router, cfg *AppConfig, apps ...Application)
Apps 注册一组应用到路由。 Deprecated: 使用 MustConfigureApplication。
func Bind ¶
Bind 将类型 T 绑定到一个懒加载单例工厂。
core.Bind(c, func(c *core.Container) (*Repo, error) {
return NewRepo(core.MustResolve[*DB](c)), nil
})
func BindFrameworkApp ¶
BindFrameworkApp 将请求绑定到处理它的框架 App。由 HTTP 适配器在管线首部调用。
func BindInterface ¶
BindInterface 将接口类型 I 绑定到返回 T 的工厂。调用方通常用具体类型构造并断言实现 I。
core.BindInterface[Repository, *MySQLRepo](c, func(c *core.Container) (*MySQLRepo, error) {
return &MySQLRepo{}, nil
})
之后即可 core.Resolve[Repository](c) 取到 *MySQLRepo(按接口 I 作为键)。 工厂返回值若不实现 I 会返回错误。
func BindNamed ¶
BindNamed 按名称绑定类型 T 的懒加载单例工厂,与无名称绑定相互独立。
core.BindNamed[*Cache](c, "redis", func(c *core.Container) (*Cache, error) { ... })
v := core.MustResolveNamed[*Cache](c, "redis")
func BindNamedTransient ¶
BindNamedTransient 按名称绑定为瞬时服务。
func BindNamedValue ¶
BindNamedValue 按名称直接绑定一个已构造的实例。
func BindTransient ¶
BindTransient 绑定为瞬时服务,每次 Resolve 都重新构造。
func DefaultApps ¶
func DefaultApps(r Router, cfg PageConfig, apps ...Application)
DefaultApps 兼容旧写法。 Deprecated: 使用 MustConfigureApplication。
func MustConfigureApplication ¶
func MustConfigureApplication(r Router, cfg *AppConfig, apps ...Application)
MustConfigureApplication 根据配置注册应用,失败 panic。
func MustConfigureApps ¶
func MustConfigureApps(r Router, cfg PageConfig, apps ...Application)
MustConfigureApps 根据 tcfg 配置注册应用集。
func MustResolve ¶
MustResolve 解析类型 T,失败时 panic。 适用于启动期装配,此时失败应立即终止进程。
func MustResolveNamed ¶
MustResolveNamed 按名称解析,失败时 panic。
func RegisterMeta ¶
RegisterMeta 是向默认 App 登记路由元信息的兼容入口。
func ResolveNamed ¶
ResolveNamed 按名称解析类型 T 的实例。
func ValidateStruct ¶
ValidateStruct 使用默认 tvalid 校验器校验结构体的 valid tag。 如果结构体没有任何 valid tag,则直接返回 nil(跳过校验,零开销)。 这是 BindAllAndValidate 的底层实现,也可在自定义绑定场景中独立调用。
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App 是实例级框架内核。每个 App 拥有独立容器和服务实例。
func (*App) ApplicationNames ¶
ApplicationNames 返回所有已注册应用的名称。
func (*App) ConfigureApplication ¶
ConfigureApplication 合并应用配置元数据。已注册应用的显式值不会被覆盖。
func (*App) LookupApplication ¶
LookupApplication 按名称查找已注册应用。
func (*App) MountApplication ¶
func (a *App) MountApplication(r Router, app Application, cfg *AppConfig) Router
MountApplication 注册应用到路由。这是路由注册入口。
func (*App) RegisterApplication ¶
func (a *App) RegisterApplication(name string, app Application)
RegisterApplication 登记一个应用(仅存储元数据,不注册路由)。
func (*App) RegisterRouteMeta ¶
RegisterRouteMeta 在当前 App 的注册期登记路由元信息。
type AppConfig ¶
type AppConfig struct {
Path string
Prefix string
Domain string // 域名绑定(可选)
Disabled bool // 是否禁用
Priority int // 优先级(越大越优先注册)
Default bool // 是否为默认应用
Middleware []Handler
}
AppConfig 是每个应用的配置。
type AppConfigurer ¶
type AppConfigurer interface {
Config() AppConfig
}
AppConfigurer 可选接口:应用实现它来提供配置。
type AppInfo ¶
type AppInfo struct {
App Application
Config *AppConfig
Name string
}
AppInfo 包含已注册应用的信息。
type AppMiddlewarer ¶
type AppMiddlewarer interface {
Middlewares() []Handler
}
AppMiddlewarer 可选接口:应用实现它来声明专属中间件。
type Container ¶
type Container struct {
// contains filtered or unexported fields
}
Container 是类型安全的服务容器。
使用 Go 类型本身作为键,解析结果无需类型断言,且错误在编译期即可发现。
服务默认为单例且懒加载,首次 Resolve 时构造,之后复用。
providers 通过 atomic.Pointer 发布只读快照:绑定只在启动期发生, 运行期 Resolve 读取快照免加锁。
func (*Container) ResolveUntyped ¶
ResolveUntyped 按反射类型从容器解析实例。
它复用与 Resolve[T] 完全相同的绑定查找与单例缓存逻辑,区别在于键由 调用方以 reflect.Type 形式提供,从而支持在反射驱动的装配(如控制器字段注入) 中解析任意类型,无需调用方提供编译期泛型参数。
type Ctx ¶
Ctx 是 tingo 的请求上下文。
通过类型定义(而非结构体嵌入)实现零拷贝,指针转换不产生任何堆分配, 也不增加一层间接寻址。
注意:Ctx 只能通过转换获得,不要直接 new(Ctx)。
func (*Ctx) BindAll ¶
BindAll 依次绑定 uri、query、body,后者覆盖前者。
绑定顺序与语义:
- uri —— 仅在存在路由参数时执行;
- query —— 始终执行。即便 query 为空也不能跳过, 因为 `form:"page,default=1"` 这类默认值依赖此步生效;
- body —— 仅在确有请求体时执行,空体不视为错误。
校验(binding tag)在最后一步统一触发, 以保证前面步骤填入的默认值也参与校验。
func (*Ctx) BindAllAndValidate ¶
BindAllAndValidate 依次绑定 uri、query、body,然后自动校验 valid tag。
绑定完成后会自动调用 tvalid.CheckStruct(obj) 对 valid tag 进行校验。 如果绑定失败返回绑定错误,如果校验失败返回 tvalid.Errors。
用法:
type LoginReq struct {
Name string `form:"name" valid:"required|len:3,20" label:"用户名"`
Age int `form:"age" valid:"min:1|max:120"`
}
var req LoginReq
if err := c.BindAllAndValidate(&req); err != nil {
// 绑定或校验失败
c.JSON(400, gin.H{"error": err.Error()})
return
}
func (*Ctx) Body ¶
Body 读取并返回请求体原始字节。可重复调用:首次读取后会将内容 还原回 Request.Body,因此后续读取(包括内部的 Bind/ShouldBind) 都能拿到完整数据,不会返回空。
func (*Ctx) DefaultPost ¶
DefaultPost 返回 POST 表单字段,不存在时返回默认值。
func (*Ctx) DefaultQuery ¶
DefaultQuery 返回 URL query 参数,不存在时返回默认值。
func (*Ctx) Files ¶
func (c *Ctx) Files(name string) ([]*multipart.FileHeader, error)
Files 返回上传的多个同名文件。
func (*Ctx) Route ¶
Route 返回当前请求的路由归属信息。 未启用元信息绑定或路由未登记时返回空的 RouteMeta,不会返回 nil。
本方法零分配:FullPath 由 gin 在路由匹配时已填好, 拼接键使用栈上小字符串,map 查找不产生逃逸。
func (*Ctx) SaveFile ¶
func (c *Ctx) SaveFile(f *multipart.FileHeader, dst string) error
SaveFile 保存上传文件到指定路径。
func (*Ctx) SetCookie ¶
func (c *Ctx) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) *Ctx
SetCookie 设置 cookie。
func (*Ctx) StringStatus ¶
StringStatus 以指定状态码输出纯文本。
type CtxKey ¶
type CtxKey[T any] struct { // contains filtered or unexported fields }
CtxKey 是类型安全的请求级键。
用法:
var UserKey = core.NewCtxKey[*model.User]("auth.user")
UserKey.Set(c, u)
u, ok := UserKey.Get(c)
type DriverFactory ¶
DriverFactory 是创建驱动的工厂函数。
type DriverManager ¶
type DriverManager[Config, Driver any] struct { // contains filtered or unexported fields }
DriverManager 按连接名惰性创建并缓存驱动实例。
func NewDriverManager ¶
func NewDriverManager[Config, Driver any](cfg DriverManagerConfig[Config, Driver]) *DriverManager[Config, Driver]
NewDriverManager 创建一个驱动管理器。
func (*DriverManager[Config, Driver]) Close ¶
func (m *DriverManager[Config, Driver]) Close(ctx context.Context) error
Close 关闭所有已创建的驱动实例(逆序关闭)。
func (*DriverManager[Config, Driver]) Connection ¶
func (m *DriverManager[Config, Driver]) Connection(ctx context.Context, names ...string) (Driver, error)
Connection 获取指定连接名的驱动实例。未指定则使用默认连接。
type DriverManagerConfig ¶
type DriverManagerConfig[Config, Driver any] struct { Registry *DriverRegistry[Config, Driver] Default func() string Resolve func(name string) (Config, error) Type func(Config) string Close func(context.Context, Driver) error }
DriverManagerConfig 是 DriverManager 的配置项。
type DriverRegistry ¶
type DriverRegistry[Config, Driver any] struct { // contains filtered or unexported fields }
DriverRegistry 是泛型驱动注册表,按名称管理工厂函数。
func NewDriverRegistry ¶
func NewDriverRegistry[Config, Driver any]() *DriverRegistry[Config, Driver]
NewDriverRegistry 创建一个新的驱动注册表。
func (*DriverRegistry[Config, Driver]) Factory ¶
func (r *DriverRegistry[Config, Driver]) Factory(name string) (DriverFactory[Config, Driver], bool)
Factory 按名称获取驱动工厂。
func (*DriverRegistry[Config, Driver]) Names ¶
func (r *DriverRegistry[Config, Driver]) Names() []string
Names 返回所有已注册的驱动名称,排序后返回。
func (*DriverRegistry[Config, Driver]) Register ¶
func (r *DriverRegistry[Config, Driver]) Register(name string, factory DriverFactory[Config, Driver]) error
Register 注册一个驱动工厂。名称不区分大小写。
type Handler ¶
type Handler func(*Ctx)
Handler 是 tingo 的原生 handler,与 gin.HandlerFunc 内存布局一致。 由于 Ctx 与 gin.Context 布局相同,Handler 与 gin.HandlerFunc 之间 可以通过 unsafe-free 的函数值转换互转,无运行时开销。
func Adapt ¶
Adapt 将多种 handler 签名统一适配为 Handler。
支持的签名(按性能从高到低排列,前三种为零反射快路径):
func(*Ctx) 原生,零开销 func(*gin.Context) gin 原生,零开销 func(*Ctx) error 带错误,零开销 func(*Ctx) (T, error) 泛型返回,需用 W 包装 func(ctx context.Context, req *Req) (*Res, error) 反射适配
反射仅发生在注册期,运行时通过预编译的闭包执行, 每请求成本为一次 sync.Pool 取用 + 反射 Call。 对性能敏感的路由请使用前三种签名或 codegen 生成的适配器。
func HandlerOf ¶
func HandlerOf(h gin.HandlerFunc) Handler
HandlerOf 将 gin.HandlerFunc 转为 Handler,用于复用 gin 生态中间件。零成本。
type PageConfig ¶
PageConfig 是从配置文件中读取单应用页面配置的接口。
type Responder ¶
type Responder interface {
// Reply 在 handler 成功返回时调用。data 可能为 nil。
Reply(c *Ctx, data any)
// Fail 在 handler 返回错误时调用。
Fail(c *Ctx, err error)
}
Responder 决定 handler 返回值如何写入响应。 框架提供默认实现,业务可全局替换以定制响应格式。
type RouteMeta ¶
type RouteMeta struct {
// App 是所属应用名。
App string
// Controller 是控制器名。
Controller string
// Action 是动作名。
Action string
}
RouteMeta 描述一条路由的静态归属信息。
该结构在「注册期」构造一次并被同一路由的所有请求共享, 它是只读的,可安全并发访问。
type Router ¶
type Router interface {
Use(handler ...Handler) Router
// UseOrdered 按优先级升序追加中间件(数值越小越先执行,同级保序)。
UseOrdered(mws ...WeightedMiddleware) Router
Group(relativePath string, fn func(Router), mws ...Handler) Router
// Module 创建按模块名隔离的子路由组。
// 自动套 /{module} 前缀并与外层中间件隔离,模块内再 Group 时基于该前缀展开。
Module(name string, fn func(Router), mws ...Handler) Router
GET(path string, handler any) Router
POST(path string, handler any) Router
PUT(path string, handler any) Router
DELETE(path string, handler any) Router
PATCH(path string, handler any) Router
HEAD(path string, handler any) Router
OPTIONS(path string, handler any) Router
Any(path string, handler any) Router
Controller(path string, controller any) Router
Resource(path string, controller any) Router
}
Router 定义了路由注册接口。
type Service ¶
type Service interface {
Name() string
DependsOn() []string
Register(*App) error
Boot(context.Context, *App) error
Shutdown(context.Context) error
}
Service 是框架能力的生命周期单元。 Register 仅声明容器绑定;Boot 才建立连接、启动 goroutine 或挂载资源。
type WeightedMiddleware ¶
WeightedMiddleware 是带优先级的中间件。
数值越小越先执行(全局 -> 模块 -> 控制器 -> 动作 由小到大注册)。 同级按注册顺序。通过 Router.UseOrdered 注册。