README ¶
web
web 是一个比较完整的 API 开发框架,相对于简单的路由,提供了更多的便利功能。 如果你只是需要一个简单的路由工具,那么你可以移步到 mux。
package main
import "github.com/issue9/web"
import "github.com/issue9/web/server"
// main.go
func main() {
srv, err := server.New("web", "1.0.0", &server.Options{})
router := srv.Routers().New()
router.Get("/admins", getAdmins).
Get("/groups", getGroups)
srv.Serve()
}
func getAdmins(ctx* web.Context) web.Responser {
return ctx.NotImplemented()
}
func getGroups(ctx* web.Context) web.Responser {
return ctx.NotImplemented()
}
字符集和文档类型
https://www.iana.org/assignments/character-sets/character-sets.xhtml 中列出的字符集都能自动转换。
文档类型由 Server.Mimetypes
指定。
package main
import (
"github.com/issue9/web"
"github.com/issue9/web/server"
"github.com/issue9/web/mimetype/json"
"github.com/issue9/web/mimetype/xml"
)
srv := server.New("app", "1.0.0", &server.Options{
Codec: web.NewCodec().
AddMimetype(xml.Mimetype, json.Marshal, json.Unmarshal, xml.ProblemMimetype).
AddMimetype(xml.Mimetype, xml.Marshal, xml.Unmarshal, xml.ProblemMimetype)
}
})
srv.Serve()
客户端只要在请求时设置 Accept 报头就可返回相应类型的数据,而 Accept-Charset 报头可设置接收的字符集。 Content-Type 则可以有向服务器指定提交内容的文档类型和字符集。
错误处理
框架根据 RFC7807 提供了一种输出错误信息内容的机制。
插件
- https://github.com/issue9/webuse 提供了常用的中间件和插件。
- https://github.com/issue9/webfilter 提供了常用的验证和修正数据的方法。
工具
https://github.com/issue9/web/releases 提供了一个简易的辅助工具。可以帮助用户完成以下工作:
- 提取和更新本地化信息;
- 生成 openapi 文档。需要在注释中写一定的注解;
- 热编译项目;
macOS 和 linux 用户可以直接使用 brew 进行安装:
brew tap caixw/brew
brew install caixw/brew/web
版权
Documentation ¶
Overview ¶
Package web 通用的 web 开发框架
NOTE: 所有以 Internal 开头的函数和对象都是模块内部使用的。
Index ¶
- Constants
- func ErrExitContext() error
- func IsProblem(status int) bool
- func NewError(status int, err error) error
- func NewLocaleError(format string, v ...any) error
- func NewStackError(err error) error
- func SprintError(p *localeutil.Printer, detail bool, err error) string
- type AttrLogs
- type Cache
- type Client
- func (c *Client) Client() *http.Client
- func (c *Client) Delete(path string, resp any, pb ProblemBuilder) error
- func (c *Client) Do(method, path string, req, resp any, pb ProblemBuilder) error
- func (c *Client) Get(path string, resp any, pb ProblemBuilder) error
- func (c *Client) NewRequest(method, path string, body any) (resp *http.Request, err error)
- func (c *Client) ParseResponse(rsp *http.Response, resp any, pb ProblemBuilder) (err error)
- func (c *Client) Patch(path string, req, resp any, pb ProblemBuilder) error
- func (c *Client) Post(path string, req, resp any, pb ProblemBuilder) error
- func (c *Client) Put(path string, req, resp any, pb ProblemBuilder) error
- func (c *Client) URL(path string) (string, error)
- type Codec
- type Context
- func (ctx *Context) Begin() time.Time
- func (ctx *Context) Charset() string
- func (ctx *Context) ClientIP() string
- func (ctx *Context) Deadline() (time.Time, bool)
- func (ctx *Context) DelVar(key any)
- func (ctx *Context) Done() <-chan struct{}
- func (ctx *Context) Encoding() string
- func (ctx *Context) Err() error
- func (ctx *Context) Error(err error, problemID string) *Problem
- func (ctx *Context) GetVar(key any) (any, bool)
- func (ctx *Context) Header() http.Header
- func (ctx *Context) ID() string
- func (ctx *Context) IsXHR() bool
- func (ctx *Context) LanguageTag() language.Tag
- func (ctx *Context) LocalePrinter() *message.Printer
- func (ctx *Context) Location() *time.Location
- func (ctx *Context) Logs() *AttrLogs
- func (ctx *Context) Marshal(v any) ([]byte, error)
- func (ctx *Context) Mimetype(problem bool) string
- func (ctx *Context) NewFilterContext(exitAtError bool) *FilterContext
- func (ctx *Context) NotFound() *Problem
- func (ctx *Context) NotImplemented() *Problem
- func (ctx *Context) Now() time.Time
- func (ctx *Context) OnExit(f OnExitContextFunc)
- func (ctx *Context) ParseTime(layout, value string) (time.Time, error)
- func (ctx *Context) PathID(key, id string) (int64, Responser)
- func (ctx *Context) PathInt64(key, id string) (int64, Responser)
- func (ctx *Context) PathString(key, id string) (string, Responser)
- func (ctx *Context) Paths(exitAtError bool) *Paths
- func (ctx *Context) Problem(id string) *Problem
- func (ctx *Context) Queries(exitAtError bool) (*Queries, error)
- func (ctx *Context) QueryObject(exitAtError bool, v any, id string) Responser
- func (ctx *Context) Read(exitAtError bool, v any, id string) Responser
- func (ctx *Context) Render(status int, body any)
- func (ctx *Context) Request() *http.Request
- func (ctx *Context) RequestBody() io.Reader
- func (ctx *Context) Route() types.Route
- func (ctx *Context) Server() Server
- func (ctx *Context) SetCharset(charset string)
- func (ctx *Context) SetCookies(c ...*http.Cookie)
- func (ctx *Context) SetEncoding(enc string)
- func (ctx *Context) SetLanguage(tag language.Tag)
- func (ctx *Context) SetLocation(l *time.Location)
- func (ctx *Context) SetMimetype(mimetype string)
- func (ctx *Context) SetVar(key, val any)
- func (ctx *Context) Sprintf(key string, v ...any) string
- func (ctx *Context) Unmarshal(v any) error
- func (ctx *Context) Unwrap() http.ResponseWriter
- func (ctx *Context) Value(key any) any
- func (ctx *Context) Wrap(f func(http.ResponseWriter) http.ResponseWriter)
- func (ctx *Context) Write(bs []byte) (n int, err error)
- func (ctx *Context) WriteHeader(status int)
- func (ctx *Context) Wrote() bool
- type FieldError
- type Filter
- type FilterContext
- func (v *FilterContext) Add(f filter.Filter) *FilterContext
- func (v *FilterContext) AddError(name string, err error) *FilterContext
- func (v *FilterContext) AddFilter(name string, f Filter) *FilterContext
- func (v *FilterContext) AddReason(name string, reason LocaleStringer) *FilterContext
- func (v *FilterContext) Context() *Context
- func (v *FilterContext) New(name string, f func(c *FilterContext)) *FilterContext
- func (v *FilterContext) Problem(id string) Responser
- func (v *FilterContext) When(cond bool, f func(v *FilterContext)) *FilterContext
- type HandlerFunc
- type InternalServer
- func (s *InternalServer) Cache() cache.Cleanable
- func (s *InternalServer) CanCompress() bool
- func (s *InternalServer) Close()
- func (s *InternalServer) Config() *config.Config
- func (s *InternalServer) Deadline() (time.Time, bool)
- func (s *InternalServer) Done() <-chan struct{}
- func (s *InternalServer) Err() error
- func (s *InternalServer) ID() string
- func (s *InternalServer) Locale() Locale
- func (s *InternalServer) Location() *time.Location
- func (s *InternalServer) Logs() *Logs
- func (s *InternalServer) Mimetypes() iter.Seq2[string, string]
- func (s *InternalServer) NewClient(c *http.Client, sel selector.Selector, m string, ...) *Client
- func (s *InternalServer) NewContext(w http.ResponseWriter, r *http.Request, route types.Route) *Context
- func (s *InternalServer) Now() time.Time
- func (s *InternalServer) OnClose(f ...func() error)
- func (s *InternalServer) OnExitContext(f ...OnExitContextFunc)
- func (s *InternalServer) ParseTime(layout, value string) (time.Time, error)
- func (s *InternalServer) Problems() *Problems
- func (s *InternalServer) Routers() *Routers
- func (s *InternalServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *InternalServer) Services() *Services
- func (s *InternalServer) SetCompress(enable bool)
- func (s *InternalServer) UniqueID() string
- func (s *InternalServer) Uptime() time.Time
- func (s *InternalServer) Use(p ...Plugin)
- func (s *InternalServer) Value(key any) any
- func (s *InternalServer) Vars() *sync.Map
- func (s *InternalServer) Version() string
- type Job
- type JobFunc
- type Locale
- type LocaleProblem
- type LocaleStringer
- type Logger
- type Logs
- type MarshalFunc
- type Middleware
- type MiddlewareFunc
- type OnExitContextFunc
- type Paths
- type Plugin
- type PluginFunc
- type Prefix
- type Problem
- type ProblemBuilder
- type ProblemParam
- type Problems
- type Queries
- func (q *Queries) Bool(key string, def bool) bool
- func (q *Queries) Float64(key string, def float64) float64
- func (q *Queries) Int(key string, def int) int
- func (q *Queries) Int64(key string, def int64) int64
- func (q *Queries) Object(v any)
- func (q *Queries) Problem(id string) Responser
- func (q *Queries) String(key, def string) string
- type QueryUnmarshaler
- type Resource
- type Responser
- func Created(v any, location string) Responser
- func KeepAlive(ctx context.Context) Responser
- func NoContent() Responser
- func NotModified(etag func() (string, bool), body func() (any, error)) Responser
- func OK(v any) Responser
- func Redirect(status int, url string) Responser
- func Response(status int, body any, kv ...string) Responser
- func Status(code int, kv ...string) Responser
- type ResponserFunc
- type Router
- type RouterMatcher
- type RouterMatcherFunc
- type RouterOption
- func WithAllowedCORS(maxAge int) RouterOption
- func WithAnyInterceptor(rule string) RouterOption
- func WithCORS(origin, allowHeaders, exposedHeaders []string, maxAge int, ...) RouterOption
- func WithDenyCORS() RouterOption
- func WithDigitInterceptor(rule string) RouterOption
- func WithInterceptor(f mux.InterceptorFunc, rule ...string) RouterOption
- func WithRecovery(status int, l *Logger) RouterOption
- func WithTrace(body bool) RouterOption
- func WithURLDomain(prefix string) RouterOption
- func WithWordInterceptor(rule string) RouterOption
- type Routers
- type Scheduler
- type SchedulerFunc
- type Server
- type Service
- type ServiceFunc
- type Services
- func (srv *Services) Add(title LocaleStringer, f Service) context.CancelFunc
- func (srv *Services) AddAt(title LocaleStringer, job JobFunc, at time.Time, delay bool) context.CancelFunc
- func (srv *Services) AddCron(title LocaleStringer, f JobFunc, spec string, delay bool) context.CancelFunc
- func (srv *Services) AddFunc(title LocaleStringer, f func(context.Context) error) context.CancelFunc
- func (srv *Services) AddJob(title LocaleStringer, job JobFunc, scheduler Scheduler, delay bool) context.CancelFunc
- func (srv *Services) AddTicker(title LocaleStringer, job JobFunc, dur time.Duration, imm, delay bool) context.CancelFunc
- func (srv *Services) Visit(visit func(title LocaleStringer, state State, err error))
- func (srv *Services) VisitJobs(visit func(*Job))
- type State
- type StringPhrase
- type UnmarshalFunc
Constants ¶
const ( ProblemAboutBlank = "about:blank" ProblemBadRequest = "400" ProblemPaymentRequired = "402" ProblemForbidden = "403" ProblemNotFound = "404" ProblemMethodNotAllowed = "405" ProblemNotAcceptable = "406" ProblemProxyAuthRequired = "407" ProblemRequestTimeout = "408" ProblemConflict = "409" ProblemGone = "410" ProblemLengthRequired = "411" ProblemPreconditionFailed = "412" ProblemRequestEntityTooLarge = "413" ProblemRequestURITooLong = "414" ProblemUnsupportedMediaType = "415" ProblemRequestedRangeNotSatisfiable = "416" ProblemExpectationFailed = "417" ProblemTeapot = "418" ProblemMisdirectedRequest = "421" ProblemUnprocessableEntity = "422" ProblemLocked = "423" ProblemFailedDependency = "424" ProblemTooEarly = "425" ProblemUpgradeRequired = "426" ProblemPreconditionRequired = "428" ProblemTooManyRequests = "429" ProblemRequestHeaderFieldsTooLarge = "431" ProblemInternalServerError = "500" ProblemNotImplemented = "501" ProblemBadGateway = "502" ProblemGatewayTimeout = "504" ProblemHTTPVersionNotSupported = "505" ProblemVariantAlsoNegotiates = "506" ProblemInsufficientStorage = "507" ProblemLoopDetected = "508" ProblemNotExtended = "510" ProblemNetworkAuthenticationRequired = "511" )
const Version = "0.100.7"
Version 当前框架的版本
Variables ¶
This section is empty.
Functions ¶
func ErrExitContext ¶ added in v0.98.0
func ErrExitContext() error
ErrExitContext 当已经退出 Context 对象时还对其进行操作将返回此错误
func NewError ¶ added in v0.85.0
NewError 用 HTTP 状态码包装一个错误信息
status 表示 HTTP 状态码; err 被包装的错误信息,如果是空值,将会 panic;
此方法返回的错误,在 Context.Error 和 WithRecovery 中会被识别且按指定的状态码输出。
func NewLocaleError ¶ added in v0.62.0
NewLocaleError 本地化的错误信息
func NewStackError ¶ added in v0.61.0
NewStackError 为 err 带上调用信息
位置从调用 NewStackError 开始。如果 err 为 nil,则返回 nil。 多次调用 NewStackError 包装,则返回第一次包装的返回值。
func SprintError ¶ added in v0.93.0
func SprintError(p *localeutil.Printer, detail bool, err error) string
SprintError 将 err 转换为字符串
p 如果 err 实现了 LocaleStringer,将采用 p 进行转换; detail 是否输出调用堆栈;
Types ¶
type Client ¶ added in v0.85.0
type Client struct {
// contains filtered or unexported fields
}
Client 用于访问远程的客户端
NOTE: 远程如果不是 Server 实现的服务,可能无法正确处理返回对象。
func NewClient ¶ added in v0.85.0
func NewClient( client *http.Client, codec *Codec, s selector.Selector, marshalName string, marshal func(any) ([]byte, error), requestIDKey string, requestIDGen func() string, ) *Client
NewClient 创建 Client 实例
client 如果为空,表示采用 &http.Client{} 作为默认值; marshalName 和 marshal 表示编码的名称和方法; requestIDKey 表示 x-request-id 的报头名称,如果为空则表示不需要; requestIDGen 表示生成 x-request-id 值的方法;
func (*Client) Delete ¶ added in v0.85.0
func (c *Client) Delete(path string, resp any, pb ProblemBuilder) error
func (*Client) Do ¶ added in v0.85.0
func (c *Client) Do(method, path string, req, resp any, pb ProblemBuilder) error
Do 开始新的请求
req 为提交的对象,最终是由初始化参数的 marshal 进行编码; resp 为返回的数据的写入对象,必须是指针类型; 有关 pb 的说明可参考 Client.ParseResponse。
func (*Client) Get ¶ added in v0.85.0
func (c *Client) Get(path string, resp any, pb ProblemBuilder) error
func (*Client) ParseResponse ¶ added in v0.85.0
ParseResponse 从 http.Response 解析并获取返回对象
如果不能正确获得返回的内容将返回普通的 error; 如果内容获取正常,将内容解码至 resp,或是在非正常状态码下解码至由 pb 构建的 Problem 对象中, 并作为 error 对象返回。如果 pb 参数为 nil,将被赋予 &Problem{} 的返回值。 之所以由用户指定 pb 参数,是因为 [Problem.Extensions] 的类型不确定。
func (*Client) Patch ¶ added in v0.85.0
func (c *Client) Patch(path string, req, resp any, pb ProblemBuilder) error
func (*Client) Post ¶ added in v0.85.0
func (c *Client) Post(path string, req, resp any, pb ProblemBuilder) error
type Codec ¶ added in v0.86.0
type Codec struct {
// contains filtered or unexported fields
}
Codec 编码解码工具
包含了压缩方法和媒体类型的处理
func (*Codec) AddCompressor ¶ added in v0.86.0
func (e *Codec) AddCompressor(c compressor.Compressor, t ...string) *Codec
AddCompressor 添加新的压缩算法
t 表示适用的 content-type 类型,可以包含通配符,比如:
application/json text/* *
如果为空,则和 * 是相同的,表示匹配所有。
func (*Codec) AddMimetype ¶ added in v0.86.0
func (e *Codec) AddMimetype(name string, m MarshalFunc, u UnmarshalFunc, problem string) *Codec
AddMimetype 添加对媒体类型的编解码函数
type Context ¶
type Context struct {
// contains filtered or unexported fields
}
Context 根据当次 HTTP 请求生成的上下文内容
Context 同时也实现了 http.ResponseWriter 接口, 但是不推荐非必要情况下直接使用 http.ResponseWriter 的接口方法, 而是采用返回 Responser 的方式向客户端输出内容。
func (*Context) ClientIP ¶ added in v0.34.0
ClientIP 返回客户端的 IP 地址及端口
获取顺序如下:
- X-Forwarded-For 的第一个元素
- Remote-Addr 报头
- X-Read-IP 报头
func (*Context) Done ¶ added in v0.98.0
func (ctx *Context) Done() <-chan struct{}
Done 接口 context.Context 的方法
func (*Context) Error ¶ added in v0.34.0
Error 将 err 输出到 ERROR 通道并尝试以指定 id 的 Problem 返回
如果 id 为空,尝试以下顺序获得值:
- err 是否是由 NewError 创建,如果是则采用 err.Status 取得 ID 值;
- err 是否为 fs.ErrPermission,如果是采用 ProblemForbidden 作为 ID;
- err 是否为 fs.ErrNotExist,如果是采用 ProblemNotFound 作为 ID;
- 采用 ProblemInternalServerError;
func (*Context) ID ¶ added in v0.83.0
ID 当前请求的唯一 ID
一般源自客户端的 X-Request-ID 报头,如果不存在,则由 [Server.UniqueID] 生成。
func (*Context) LanguageTag ¶ added in v0.83.0
func (*Context) LocalePrinter ¶ added in v0.34.0
func (*Context) NewFilterContext ¶ added in v0.87.0
func (ctx *Context) NewFilterContext(exitAtError bool) *FilterContext
NewFilterContext 声明 FilterContext 对象
func (*Context) NotImplemented ¶ added in v0.34.0
func (*Context) OnExit ¶ added in v0.83.0
func (ctx *Context) OnExit(f OnExitContextFunc)
OnExit 注册退出当前请求时的处理函数
此方法添加的函数会先于 [Server.OnExitContext] 添加的函数执行。
func (*Context) PathID ¶ added in v0.83.0
PathID 获取地址参数中表示 key 的值并转换成大于 0 的 int64
NOTE: 若需要获取多个参数,使用 Context.Paths 会更方便。
func (*Context) PathInt64 ¶ added in v0.83.0
PathInt64 取地址参数中的 key 表示的值并尝试转换成 int64 类型
NOTE: 若需要获取多个参数,可以使用 Context.Paths 获取会更方便。
func (*Context) PathString ¶ added in v0.83.0
PathString 取地址参数中的 key 表示的值并转换成 string 类型
NOTE: 若需要获取多个参数,可以使用 Context.Paths 获取会更方便。
func (*Context) QueryObject ¶ added in v0.34.0
QueryObject 将查询参数解析到一个对象中
func (*Context) Read ¶ added in v0.34.0
Read 从客户端读取数据并转换成 v 对象
如果 v 实现了 Filter 接口,则在读取数据之后,会调用该接口方法。 如果验证失败,会返回以 id 作为错误代码的 Problem 对象。
func (*Context) Render ¶ added in v0.34.0
Render 向客户端输出对象
status 想输出给用户状态码,如果出错,那么最终展示给用户的状态码可能不是此值; body 表示输出的对象,该对象最终调用 Context.Marshal 编码;
func (*Context) RequestBody ¶ added in v0.83.0
RequestBody 用户提交的内容
func (*Context) SetCharset ¶ added in v0.83.0
SetCharset 设置输出的字符集
不会修改 Context.Request 中的 Accept-Charset 报头,如果需要同时修改此报头 可以通过 [Server.NewContext] 构建一个新 Context 对象。
func (*Context) SetCookies ¶ added in v0.83.0
SetCookies 输出一组 Cookie
func (*Context) SetEncoding ¶ added in v0.83.0
SetEncoding 设置输出的压缩编码
不会修改 Context.Request 中的 Accept-Encoding 报头,如果需要同时修改此报头 可以通过 [Server.NewContext] 构建一个新 Context 对象。
func (*Context) SetLanguage ¶ added in v0.83.0
SetLanguage 修改输出的语言
不会修改 Context.Request 中的 Accept-Language 报头,如果需要同时修改此报头 可以通过 [Server.NewContext] 构建一个新 Context 对象。
func (*Context) SetMimetype ¶ added in v0.83.0
SetMimetype 设置输出的格式
不会修改 Context.Request 中的 Accept 报头,如果需要同时修改此报头 可以通过 [Server.NewContext] 构建一个新 Context 对象。
func (*Context) Unwrap ¶ added in v0.83.0
func (ctx *Context) Unwrap() http.ResponseWriter
Unwrap http.ResponseController 通过此方法返回底层的 http.ResponseWriter
func (*Context) Wrap ¶ added in v0.86.0
func (ctx *Context) Wrap(f func(http.ResponseWriter) http.ResponseWriter)
Wrap 替换底层的 http.ResponseWriter 对象
f 用于构建新的 http.ResponseWriter 对象,其原型为:
func(w http.ResponseWriter) http.ResponseWriter
其中 w 表示原本与 Context 关联的对象,返回一个新的替换对象。 如果已经有内容输出,此操作将会 panic。
func (*Context) WriteHeader ¶ added in v0.83.0
WriteHeader 向客户端输出 HTTP 状态码
NOTE: 如非必要,应该通过 Context.Render 输出。
type FieldError ¶ added in v0.66.1
type FieldError = config.FieldError
FieldError 表示配置文件中的字段错误
func NewFieldError ¶ added in v0.66.1
func NewFieldError(field string, msg any) *FieldError
NewFieldError 返回表示配置文件错误的对象
field 表示错误的字段名; msg 表示错误信息,可以是任意类型,如果 msg 是 FieldError 类型, 那么此操作相当于调用了 [FieldError.AddFieldParent];
type Filter ¶ added in v0.33.0
type Filter interface {
Filter(*FilterContext)
}
Filter 用户提交数据的验证修正接口
type FilterContext ¶ added in v0.86.0
type FilterContext struct {
// contains filtered or unexported fields
}
FilterContext 处理由过滤器生成的各错误
func (*FilterContext) Add ¶ added in v0.86.0
func (v *FilterContext) Add(f filter.Filter) *FilterContext
Add 添加由过滤器 f 返回的错误信息
func (*FilterContext) AddError ¶ added in v0.86.0
func (v *FilterContext) AddError(name string, err error) *FilterContext
AddError 直接添加一条类型为 [error] 的错误信息
func (*FilterContext) AddFilter ¶ added in v0.86.0
func (v *FilterContext) AddFilter(name string, f Filter) *FilterContext
AddFilter 验证实现了 Filter 接口的对象
func (*FilterContext) AddReason ¶ added in v0.86.0
func (v *FilterContext) AddReason(name string, reason LocaleStringer) *FilterContext
AddReason 直接添加一条错误信息
func (*FilterContext) Context ¶ added in v0.86.0
func (v *FilterContext) Context() *Context
Context 返回关联的 Context 实例
func (*FilterContext) New ¶ added in v0.86.0
func (v *FilterContext) New(name string, f func(c *FilterContext)) *FilterContext
New 声明验证的子对象
name 为 f 中验证对象的整体名称; f 为验证方法,其原型为 func(fp *FilterContext) 往 c 参数写入的信息,其字段名均会以 name 作为前缀写入到当前对象 v 中。 c 的各种属性均继承自 v。
func (*FilterContext) Problem ¶ added in v0.86.0
func (v *FilterContext) Problem(id string) Responser
Problem 如果有错误信息转换成 Problem 否则返回 nil
func (*FilterContext) When ¶ added in v0.86.0
func (v *FilterContext) When(cond bool, f func(v *FilterContext)) *FilterContext
When 只有满足 cond 才执行 f 中的验证
f 中的 v 即为当前对象;
type HandlerFunc ¶ added in v0.33.0
HandlerFunc 路由的处理函数原型
向客户端输出内容的有两种方法,一种是通过 Context.Write 方法; 或是返回 Responser 对象。前者在调用 Context.Write 时即输出内容, 后者会在整个请求退出时才将 Responser 进行编码输出。
返回值可以为空,表示在中间件执行过程中已经向客户端输出同内容。
type InternalServer ¶ added in v0.87.0
type InternalServer struct {
// contains filtered or unexported fields
}
InternalServer 这是一个内部使用的类型,提供了大部分 Server 的实现。
func InternalNewServer ¶ added in v0.87.0
func InternalNewServer( s Server, name, ver string, loc *time.Location, logs *Logs, idgen func() string, l *locale.Locale, c cache.Driver, codec *Codec, requestIDKey string, problemPrefix string, onRender func(int, any) (int, any), o ...RouterOption, ) *InternalServer
InternalNewServer 声明 InternalServer
s 为实际的 Server 接口对象; requestIDKey 表示客户端提交的 X-Request-ID 报头名; problemPrefix 可以为空; onRender 在每个对象的渲染之前可以对内容进行的修改;
NOTE: 此为内部使用函数,由调用者保证参数的正确性。
NOTE: Server 的实现者,不应该重新实现 InternalServer 已经实现的接口, 否则可能出现 InternalServer 中的调用与 Server 的实现调用不同的问题。 比如重新实现了 [Server.Location],那么将出现 InternalServer 内部的 Location 与 新实现的 Location 返回不同值的情况。
func (*InternalServer) Cache ¶ added in v0.87.0
func (s *InternalServer) Cache() cache.Cleanable
func (*InternalServer) CanCompress ¶ added in v0.87.0
func (s *InternalServer) CanCompress() bool
func (*InternalServer) Close ¶ added in v0.87.0
func (s *InternalServer) Close()
func (*InternalServer) Config ¶ added in v0.87.0
func (s *InternalServer) Config() *config.Config
func (*InternalServer) Deadline ¶ added in v0.98.0
func (s *InternalServer) Deadline() (time.Time, bool)
func (*InternalServer) Done ¶ added in v0.98.0
func (s *InternalServer) Done() <-chan struct{}
func (*InternalServer) Err ¶ added in v0.98.0
func (s *InternalServer) Err() error
func (*InternalServer) ID ¶ added in v0.100.0
func (s *InternalServer) ID() string
func (*InternalServer) Locale ¶ added in v0.87.0
func (s *InternalServer) Locale() Locale
func (*InternalServer) Location ¶ added in v0.87.0
func (s *InternalServer) Location() *time.Location
func (*InternalServer) Logs ¶ added in v0.87.0
func (s *InternalServer) Logs() *Logs
func (*InternalServer) Mimetypes ¶ added in v0.99.0
func (s *InternalServer) Mimetypes() iter.Seq2[string, string]
func (*InternalServer) NewContext ¶ added in v0.87.0
func (s *InternalServer) NewContext(w http.ResponseWriter, r *http.Request, route types.Route) *Context
NewContext 将 w 和 r 包装为 Context 对象
如果出错,则会向 w 输出状态码并返回 nil。
func (*InternalServer) Now ¶ added in v0.87.0
func (s *InternalServer) Now() time.Time
func (*InternalServer) OnClose ¶ added in v0.87.0
func (s *InternalServer) OnClose(f ...func() error)
func (*InternalServer) OnExitContext ¶ added in v0.87.3
func (s *InternalServer) OnExitContext(f ...OnExitContextFunc)
func (*InternalServer) ParseTime ¶ added in v0.87.0
func (s *InternalServer) ParseTime(layout, value string) (time.Time, error)
func (*InternalServer) Problems ¶ added in v0.87.0
func (s *InternalServer) Problems() *Problems
func (*InternalServer) Routers ¶ added in v0.87.0
func (s *InternalServer) Routers() *Routers
func (*InternalServer) ServeHTTP ¶ added in v0.87.0
func (s *InternalServer) ServeHTTP(w http.ResponseWriter, r *http.Request)
func (*InternalServer) Services ¶ added in v0.87.0
func (s *InternalServer) Services() *Services
func (*InternalServer) SetCompress ¶ added in v0.87.0
func (s *InternalServer) SetCompress(enable bool)
func (*InternalServer) UniqueID ¶ added in v0.87.0
func (s *InternalServer) UniqueID() string
func (*InternalServer) Uptime ¶ added in v0.87.0
func (s *InternalServer) Uptime() time.Time
func (*InternalServer) Use ¶ added in v0.87.0
func (s *InternalServer) Use(p ...Plugin)
func (*InternalServer) Value ¶ added in v0.98.0
func (s *InternalServer) Value(key any) any
func (*InternalServer) Vars ¶ added in v0.87.0
func (s *InternalServer) Vars() *sync.Map
func (*InternalServer) Version ¶ added in v0.87.0
func (s *InternalServer) Version() string
type Locale ¶ added in v0.41.0
type Locale interface { catalog.Catalog // ID 返回默认的语言标签 ID() language.Tag // LoadMessages 从 fsys 中加载符合 glob 的本地化文件 // // 根据 [Server.Config] 处理文件格式,如果文件格式不被 [Server.Config] 支持,将无法加载。 LoadMessages(glob string, fsys ...fs.FS) error // Printer 最符合 [Locale.ID] 的 [message.Printer] 对象 Printer() *message.Printer // Sprintf 等同于 [Locale.Printer.Sprintf] Sprintf(string, ...any) string // NewPrinter 声明最符合 tag 的 [message.Printer] 对象 // // NOTE: 每当给 [Locale.SetString]、[Locale.SetMacro] 和 [Locale.Set] 传递新的 [language.Tag] // 值时,可能造成 NewPrinter 相同的入参而返回不同的返回对象的情况。 NewPrinter(tag language.Tag) *message.Printer // SetString 添加新的翻译项 // // 功能同 [catalog.Builder.SetString] SetString(tag language.Tag, key, msg string) error // SetMacro 添加新的翻译项 // // 功能同 [catalog.Builder.SetMacro] SetMacro(tag language.Tag, name string, msg ...catalog.Message) error // Set 添加新的翻译项 // // 功能同 [catalog.Builder.Set] Set(tag language.Tag, key string, msg ...catalog.Message) error }
Locale 提供与本地化相关的功能
type LocaleProblem ¶ added in v0.86.0
type LocaleProblem struct { ID string Title, Detail LocaleStringer // contains filtered or unexported fields }
func (*LocaleProblem) Type ¶ added in v0.88.2
func (p *LocaleProblem) Type() string
Type 相当于 RFC7807 的 type 属性
type LocaleStringer ¶ added in v0.43.0
type LocaleStringer = localeutil.Stringer
LocaleStringer 本地化字符串需要实在的接口
type MarshalFunc ¶ added in v0.83.0
MarshalFunc 序列化函数原型
NOTE: 自定义的 MarshalFunc 需要自行决定是否要自定义输出 Problem 和 [server.RenderResponse]。
NOTE: MarshalFunc 的作用是输出内容,所以在实现中不能调用 Context.Render 等输出方法。
NOTE: 不采用流的方式处理数据的原因是因为:编码过程中可能会出错, 此时需要修改状态码,流式的因为有内容输出,状态码也已经固定,无法修改。
type Middleware ¶ added in v0.33.0
type Middleware = types.Middleware[HandlerFunc]
type MiddlewareFunc ¶ added in v0.46.0
type MiddlewareFunc = types.MiddlewareFunc[HandlerFunc]
type OnExitContextFunc ¶ added in v0.87.3
OnExitContextFunc 表示在即将退出 Context 时执行的函数类型
其中 ctx 即为当前实例,status 则表示实际输出的状态码。
type Paths ¶ added in v0.83.0
type Paths FilterContext
Paths 提供对路径参数的处理
type PluginFunc ¶ added in v0.87.0
type PluginFunc func(Server)
func (PluginFunc) Plugin ¶ added in v0.87.0
func (f PluginFunc) Plugin(s Server)
type Prefix ¶ added in v0.33.0
type Prefix = mux.Prefix[HandlerFunc]
type Problem ¶ added in v0.80.0
type Problem struct { XMLName struct{} `xml:"problem" form:"-" cbor:"-" json:"-" html:"-" yaml:"-"` // 错误 ID Type string `json:"type" xml:"type" form:"type" cbor:"type" yaml:"type" comment:"problem type"` // 对错误的简要描述 Title string `json:"title" xml:"title" form:"title" cbor:"title" yaml:"title" comment:"problem title"` // 对错误的详细说明 Detail string `` /* 143-byte string literal not displayed */ // 指向错误发生的实例 Instance string `` /* 155-byte string literal not displayed */ // 原始的错误状态码 Status int `json:"status" xml:"status" form:"status" cbor:"status,omitempty" yaml:"status,omitempty" comment:"problem status"` // 用户提交对象各个字段的错误信息 Params []ProblemParam `` /* 145-byte string literal not displayed */ // 反馈给用户的信息 Extensions any `` /* 167-byte string literal not displayed */ }
Problem 基于 RFC7807 用于描述错误信息的对象
func (*Problem) MarshalHTML ¶ added in v0.83.0
MarshalHTML 实现 mimetype/html.Marshaler 接口
func (*Problem) WithInstance ¶ added in v0.85.0
WithInstance 指定发生错误的实例
多次调用将会覆盖之前的内容。默认为 Context.ID。
type ProblemBuilder ¶ added in v0.87.0
type ProblemBuilder = func() *Problem
type ProblemParam ¶ added in v0.83.0
type ProblemParam struct { Name string `json:"name" xml:"name" form:"name" cbor:"name" yaml:"name"` // 出错字段的名称 Reason string `json:"reason" xml:"reason" form:"reason" cbor:"reason" yaml:"reason"` // 出错信息 }
ProblemParam 单个错误字段的描述
type Problems ¶ added in v0.86.0
type Problems struct {
// contains filtered or unexported fields
}
func (*Problems) Add ¶ added in v0.86.0
func (ps *Problems) Add(s int, p ...*LocaleProblem) *Problems
Add 添加新项
NOTE: 已添加的内容无法修改,如果确实有需求,只能通过修改翻译项的方式间接进行修改。
func (*Problems) Visit ¶ added in v0.86.0
func (ps *Problems) Visit(visit func(int, *LocaleProblem))
Visit 遍历错误代码
visit 签名:
func(status int, p *LocaleProblem)
status 该错误代码反馈给用户的 HTTP 状态码;
type Queries ¶ added in v0.34.0
type Queries struct {
// contains filtered or unexported fields
}
Queries 提供对查询参数的处理
func (*Queries) Bool ¶ added in v0.34.0
Bool 从查询参数中获取指定名称的值
若不存在则返回 def 作为其默认值。若是无法转换,则会保存错误信息并返回 def。
func (*Queries) Float64 ¶ added in v0.34.0
Float64 从查询参数中获取指定名称的值
若不存在则返回 def 作为其默认值。若是无法转换,则会保存错误信息并返回 def。
func (*Queries) Int ¶ added in v0.34.0
Int 从查询参数中获取指定名称的值
若不存在则返回 def 作为其默认值。若是无法转换,则会保存错误信息并返回 def。
func (*Queries) Int64 ¶ added in v0.34.0
Int64 从查询参数中获取指定名称的值
若不存在则返回 def 作为其默认值。若是无法转换,则会保存错误信息并返回 def。
type QueryUnmarshaler ¶ added in v0.58.0
type QueryUnmarshaler = query.Unmarshaler
QueryUnmarshaler 对查询参数的解析接口
type Resource ¶ added in v0.33.0
type Resource = mux.Resource[HandlerFunc]
type Responser ¶ added in v0.40.0
type Responser interface { // Apply 通过 [Context] 将当前内容渲染到客户端 // // 在调用 Apply 之后,就不再使用 [Responser] 对象。 // 如果你的对象支持 [sync.Pool] 的复用方式,可以在此方法中回收内存。 Apply(*Context) }
Responser 向客户端输出对象需要实现的接口
func NotModified ¶ added in v0.71.0
NotModified 决定何时可返回 304 状态码
etag 返回当前内容关联的 ETag 报头内容,其原型为:
func()(etag string, weak bool)
etag 表示对应的 etag 报头,需要包含双绰号,但是不需要 W/ 前缀,weak 是否为弱验证。
body 获取返回给客户端的报文主体对象,其原型如下:
func()(body any, err error)
如果返回 body 的是 []byte 类型,会原样输出,其它类型则按照 Context.Marshal 进行转换成 []byte 之后输出。 body 可能参与了 etag 的计算,为了防止重复生成 body,所以此函数允许 body 直接为 []byte 类型, 在不需要 body 参与计算 etag 的情况下,应该返回非 []byte 类型的 body。
type ResponserFunc ¶ added in v0.56.0
type ResponserFunc func(*Context)
func (ResponserFunc) Apply ¶ added in v0.83.0
func (f ResponserFunc) Apply(c *Context)
type Router ¶ added in v0.34.0
type Router = mux.Router[HandlerFunc]
type RouterMatcher ¶ added in v0.83.0
type RouterMatcher = mux.Matcher
type RouterMatcherFunc ¶ added in v0.87.0
type RouterMatcherFunc = mux.MatcherFunc
type RouterOption ¶ added in v0.83.0
type RouterOption = mux.Option
func WithAllowedCORS ¶ added in v0.96.0
func WithAllowedCORS(maxAge int) RouterOption
WithAllowedCORS 允许跨域请求
func WithAnyInterceptor ¶ added in v0.96.0
func WithAnyInterceptor(rule string) RouterOption
func WithCORS ¶ added in v0.96.0
func WithCORS(origin, allowHeaders, exposedHeaders []string, maxAge int, allowCredentials bool) RouterOption
WithCORS 自定义跨域请求设置项
具体参数可参考 mux.WithCORS。
func WithDigitInterceptor ¶ added in v0.96.0
func WithDigitInterceptor(rule string) RouterOption
func WithInterceptor ¶ added in v0.96.0
func WithInterceptor(f mux.InterceptorFunc, rule ...string) RouterOption
func WithRecovery ¶ added in v0.96.0
func WithRecovery(status int, l *Logger) RouterOption
WithRecovery 在路由奔溃之后的处理方式
相对于 mux.WithRecovery,提供了对 NewError 错误的处理。
func WithTrace ¶ added in v0.96.0
func WithTrace(body bool) RouterOption
WithTrace 控制 TRACE 请求是否有效
body 表示是否显示 body 内容;
func WithURLDomain ¶ added in v0.96.0
func WithURLDomain(prefix string) RouterOption
WithURLDomain 为 [Router.URL] 生成的地址带上域名
func WithWordInterceptor ¶ added in v0.96.0
func WithWordInterceptor(rule string) RouterOption
type Routers ¶ added in v0.87.0
type Routers struct {
// contains filtered or unexported fields
}
Routers 提供管理路由的接口
func (*Routers) New ¶ added in v0.87.0
func (r *Routers) New(name string, matcher RouterMatcher, o ...RouterOption) *Router
New 声明新路由
type SchedulerFunc ¶ added in v0.28.0
type SchedulerFunc = scheduled.SchedulerFunc
type Server ¶ added in v0.25.0
type Server interface { context.Context // ID 应用的 ID 标记 ID() string // Version 应用的版本 Version() string // State 获取当前的状态 State() State // Vars 操纵共享变量的接口 Vars() *sync.Map // Location 服务器的时区信息 Location() *time.Location // Cache 返回缓存的相关接口 // // 如果要获得缓存的底层驱动接口,可以将类型转换为 [cache.Driver], // 该类型提供了 [cache.Driver.Driver] 方法可以获得相应的对象。 Cache() cache.Cleanable // Uptime 当前服务的运行时间 Uptime() time.Time // UniqueID 生成唯一性的 ID UniqueID() string // Now 返回当前时间 // // 与 [time.Now] 的区别在于 Now 的时间基于 [Server.Location] Now() time.Time // ParseTime 分析基于当前时区的时间 ParseTime(layout, value string) (time.Time, error) // Serve 开始 HTTP 服务 // // 这是个阻塞方法,会等待 [Server.Close] 执行完之后才返回。 // 始终返回非空的错误对象,如果是由 [Server.Close] 关闭的,将返回 [http.ErrServerClosed]。 Serve() error // Close 关闭服务 // // 在执行完之后会通知 Serve 返回。 // // 调用此方法表示 [Server] 的生命周期结束,对象将处于不可用状态。 Close(shutdownTimeout time.Duration) // OnClose 注册关闭服务时需要执行的函数 // // NOTE: 按注册的相反顺序执行。 OnClose(...func() error) // OnExitContext 注册在即将退出 [Context] 时需要执行的函数 OnExitContext(...OnExitContextFunc) // Config 当前项目配置文件的管理 Config() *config.Config // Logs 提供日志接口 Logs() *Logs // NewContext 从标准库的参数初始化 [Context] 对象 // // 这适合从标准库的请求中创建 [Context] 对象。 // [types.Route] 类型的参数需要用户通过 [types.NewContext] 自行创建。 // // NOTE: 由此方法创建的对象在整个会话结束后会被回收。 NewContext(http.ResponseWriter, *http.Request, types.Route) *Context // NewClient 基于当前对象的相关字段创建 [Client] 对象 // // 功能与 [NewClient] 相同,缺少的参数直接采用 [Server] 关联的字段。 NewClient(client *http.Client, s selector.Selector, marshalName string, marshal func(any) ([]byte, error)) *Client // Routers 路由管理 Routers() *Routers // SetCompress 设置压缩功能 // // 在服务器性能吃紧的情况下可以采用此方法禁用压缩。 // // NOTE: 仅对输出内容启作用,读取内容始终是按照提交的 Content-Encoding 指定算法进行解析。 SetCompress(enable bool) // CanCompress 当前是否拥有压缩功能 CanCompress() bool // Problems 提供 [Problem] 管理 Problems() *Problems // Services 服务管理接口 Services() *Services // Locale 提供本地化相关功能 Locale() Locale // Use 添加插件 Use(...Plugin) // Mimetypes 返回支持的所有媒体类型 // // 键名为 mimetype,键值为 problem 状态下的 mimetype。 Mimetypes() iter.Seq2[string, string] }
Server 服务接口
type Service ¶ added in v0.25.0
type Service interface { // Serve 运行服务 // // 这是个阻塞方法,实现者需要正确处理 [context.Context.Done] 事件。 // 如果是通过 [context.Context] 的相关操作取消的,应该返回 [context.Context.Err]。 Serve(context.Context) error }
Service 长期运行的服务需要实现的接口
type ServiceFunc ¶ added in v0.25.3
type Services ¶ added in v0.25.0
type Services struct {
// contains filtered or unexported fields
}
func (*Services) Add ¶ added in v0.83.0
func (srv *Services) Add(title LocaleStringer, f Service) context.CancelFunc
Add 添加并运行新的服务
title 是对该服务的简要说明; 返回取消该服务的操作函数,该函数同时会将整个服务从列表中删除;
func (*Services) AddAt ¶ added in v0.83.0
func (srv *Services) AddAt(title LocaleStringer, job JobFunc, at time.Time, delay bool) context.CancelFunc
AddAt 添加在某个时间点执行的任务
title 是对该服务的简要说明; at 指定的时间点; delay 是否在任务执行完之后,才计算下一次的执行时间点。
func (*Services) AddCron ¶ added in v0.83.0
func (srv *Services) AddCron(title LocaleStringer, f JobFunc, spec string, delay bool) context.CancelFunc
AddCron 添加新的定时任务
title 是对该服务的简要说明; spec cron 表达式,支持秒; delay 是否在任务执行完之后,才计算下一次的执行时间点。
func (*Services) AddFunc ¶ added in v0.83.0
func (srv *Services) AddFunc(title LocaleStringer, f func(context.Context) error) context.CancelFunc
AddFunc 将函数 f 作为服务添加并运行
func (*Services) AddJob ¶ added in v0.83.0
func (srv *Services) AddJob(title LocaleStringer, job JobFunc, scheduler Scheduler, delay bool) context.CancelFunc
AddJob 添加新的计划任务
title 是对该服务的简要说明; scheduler 计划任务的时间调度算法实现; delay 是否在任务执行完之后,才计算下一次的执行时间点。
func (*Services) AddTicker ¶ added in v0.83.0
func (srv *Services) AddTicker(title LocaleStringer, job JobFunc, dur time.Duration, imm, delay bool) context.CancelFunc
AddTicker 添加新的定时任务
title 是对该服务的简要说明; dur 时间间隔; imm 是否先执行一次该任务,如果为 true 将会排在任务执行任务队列的前列,而不是立即执行; delay 是否在任务执行完之后,才计算下一次的执行时间点。
type StringPhrase ¶ added in v0.78.0
type StringPhrase = localeutil.StringPhrase
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
web
Module
|
|
Package compressor 提供了压缩算法的实现
|
Package compressor 提供了压缩算法的实现 |
Package comptime 提供了编译期相关的处理方式
|
Package comptime 提供了编译期相关的处理方式 |
Package filter 过滤器
|
Package filter 过滤器 |
internal
|
|
Package locales 为 web 包提供了本地化的内容
|
Package locales 为 web 包提供了本地化的内容 |
Package mimetype 对媒体类型的编解码处理
|
Package mimetype 对媒体类型的编解码处理 |
cbor
Package cbor CBOR 编码
[CBOR]: https://www.rfc-editor.org/rfc/rfc8949.html
|
Package cbor CBOR 编码 [CBOR]: https://www.rfc-editor.org/rfc/rfc8949.html |
form
Package form 用于处理 www-form-urlencoded 编码
|
Package form 用于处理 www-form-urlencoded 编码 |
gob
Package gob GOB 格式的数据编码方案
[GOB]: https://pkg.go.dev/encoding/gob
|
Package gob GOB 格式的数据编码方案 [GOB]: https://pkg.go.dev/encoding/gob |
html
Package html 提供输出 HTML 内容的解码函数
|
Package html 提供输出 HTML 内容的解码函数 |
json
Package json JSON 格式的序列化方法
|
Package json JSON 格式的序列化方法 |
jsonp
Package jsonp JSONP 序列化操作
|
Package jsonp JSONP 序列化操作 |
nop
Package nop 提供了空的序列化方法
|
Package nop 提供了空的序列化方法 |
sse
Package sse SSE 的实现
[SSE]: https://html.spec.whatwg.org/multipage/server-sent-events.html
|
Package sse SSE 的实现 [SSE]: https://html.spec.whatwg.org/multipage/server-sent-events.html |
xml
Package xml XML 编码的序列化操作
|
Package xml XML 编码的序列化操作 |
yaml
Package yaml 支持 YAML 编码的序列化操作
|
Package yaml 支持 YAML 编码的序列化操作 |
Package openapi 采用 web.Middleware 中间件的形式生成 openapi 文档
|
Package openapi 采用 web.Middleware 中间件的形式生成 openapi 文档 |
Package selector 提供负载均衡的相关功能
|
Package selector 提供负载均衡的相关功能 |
Package server 提供与服务端实现相关的功能
|
Package server 提供与服务端实现相关的功能 |
app
Package app 提供了简便的方式管理 web.Server 的运行
|
Package app 提供了简便的方式管理 web.Server 的运行 |
config
Package config 从配置文件加载 server.Options
|
Package config 从配置文件加载 server.Options |
registry
Package registry 服务注册与发现
|
Package registry 服务注册与发现 |
servertest
Package servertest 为测试 web.Server 提供一些简便的功能
|
Package servertest 为测试 web.Server 提供一些简便的功能 |