README
¶
路由
本包仅用于 http 路由匹配,使用场景为路径参数解析。例如: /apis/{group}/{version}.
动机
原使用的 gin 框架,其路由匹配使用的前缀树实现,匹配速度较快。但是在使用过程中有许多的限制, 例如不能实现确定路径与通配路径同时存在(/api/core/v1 与 /{group}/{version}同时存在),相同前缀的路由无法被注册(/app1, /app2). 无法在路径中注册带":"的路由(google api 中的自定义方法),以及其他复杂的匹配问题。
语法
- 使用 '{' 与'}'定义变量匹配,其间的字符作为变量名称。可以使用 "{}"定义无名称变量。
- 使用 '*' 作为最后一个字符表示向后匹配。/{name}*,将使 name 向后匹配。
- 其他字符作为常规字符进行匹配。
路由匹配
固定匹配
-
/api/v1/
- ✅/api/v1/
- ❌/api/v1
- ❌/api/v11
- ❌/api/v789
-
/api/v1*
- ✅/api/v1/
- ✅/api/v1
- ✅/api/v11
- ✅/api/v11/hello
- ✅/api/v1/hello
- ❌/api/v789
-
/api/*1 (非后缀的*作为普通字符对待)
- ✅/api/*1
- ❌/api/v1
- ❌/api/v/1
变量匹配
-
/api/{version}
- ✅/api/*1;version=*1
- ✅/api/v1;version=v1
- ❌/api/v/1
- ❌/api/v1/
-
/api/v{version}
- ✅/api/v1;version=1
- ✅/api/vhello;version=hello
- ✅/api/v*1;version=*1
- ❌/api/v1/
- ❌/api/v/1
-
/api/v{version}*
- ✅/api/v1;version=1
- ✅/api/vhello/world;version=hello/world
- ✅/api/v/1;version=/1
- ❌/apis/v1
-
/api/v{version}/{group}
- ✅/api/v1/;version=1,group=
- ✅/api/vhello/world;version=hello,group=world
- ❌/api/v1;version=1
- ✅/api/v/1;version=,group=1
-
/person/{firstname}-{lastname}
- ✅/person/jack-ma;firstname=jack,lastname=ma
- ❌/person/jack-ma/
- ❌/person/jackma
向后匹配
-
/prefix/{path}*
- ✅/prefix/abc;path=abc
- ✅/prefix/abc/def;path=abc/def
- ❌/prefixabc;
-
/prefix*
- ✅/prefix/abc
- ✅/prefixabc/def
- ❌/pref/jackma
混合使用
若同时定义如下路由:
- /api/v{version}/{group}
- /api/v1/{group}
- /api/v1/core
则若同时满足上述条件下,路径参数少的匹配被选中。
举例:
- 请求/api/v1/core,则匹配中 /api/v1/core;
- 请求/api/v1/hello,则匹配中 /api/v1/{group};
- 请求/api/v2/hello,则匹配中 /api/v{version}/{group};
Documentation
¶
Index ¶
- Constants
- Variables
- func Build(data interface{}) *spec.Schema
- func BuildOpenAPIWebService(wss []*restful.WebService, path string, postfun func(swagger *spec.Swagger)) *restful.WebService
- func CompilePathPattern(pattern string) ([][]Element, error)
- func IntFmtProperty(format string) *spec.Schema
- func MatchSection(compiled []Element, sections []string) (bool, bool, map[string]string)
- func ObjectProperty() *spec.Schema
- func ParamIn(kind int) string
- func ParsePathTokens(path string) []string
- func TypeName(t reflect.Type) string
- type Builder
- type CompileError
- type Element
- type ElementKind
- type Function
- type Group
- type InterfaceBuildOption
- type Param
- type ParamKind
- type PathTokens
- type ResponseMeta
- type Route
- func (n *Route) Accept(mime ...string) *Route
- func (n *Route) ContentType(mime ...string) *Route
- func (n *Route) Doc(summary string) *Route
- func (n *Route) Paged() *Route
- func (n *Route) Parameters(params ...Param) *Route
- func (n *Route) Response(body interface{}, descs ...string) *Route
- func (n *Route) SetProperty(k string, v interface{}) *Route
- func (n *Route) ShortDesc(summary string) *Route
- func (n *Route) Tag(tags ...string) *Route
- func (n *Route) To(fun Function) *Route
- type Router
- func (m *Router) ANY(path string, handler gin.HandlerFunc)
- func (m *Router) DELETE(path string, handler gin.HandlerFunc)
- func (m *Router) GET(path string, handler gin.HandlerFunc)
- func (m *Router) Match(c *gin.Context) gin.HandlerFunc
- func (m *Router) MustRegister(method, path string, handler gin.HandlerFunc)
- func (m *Router) PATCH(path string, handler gin.HandlerFunc)
- func (m *Router) POST(path string, handler gin.HandlerFunc)
- func (m *Router) PUT(path string, handler gin.HandlerFunc)
- func (m *Router) Register(method, path string, handler gin.HandlerFunc) error
- type SchemaBuildFunc
- type ServeMux
- type SwaggerBuilder
- type Tree
Constants ¶
const DefinitionsRoot = "#/definitions/"
Variables ¶
var ContextKeyPathVars = struct{ name string }{/* contains filtered or unexported fields */}
using get pathvars from context.Context returns map[string]string{}
var DefaultBuilder = NewBuilder(InterfaceBuildOptionOverride)
var DefaultNotFoundHandler = gin.WrapF(http.NotFound)
var WellKnowGoTypeAsSchema = map[reflect.Type]spec.Schema{
reflect.TypeOf(json.Number("")): *spec.Float64Property(),
reflect.TypeOf(time.Time{}): *spec.DateTimeProperty(),
reflect.TypeOf(time.Duration(0)): *spec.StrFmtProperty("duration"),
}
Functions ¶
func BuildOpenAPIWebService ¶
func BuildOpenAPIWebService(wss []*restful.WebService, path string, postfun func(swagger *spec.Swagger)) *restful.WebService
func CompilePathPattern ¶
func CompilePathPattern(pattern string) ([][]Element, error)
func IntFmtProperty ¶
func IntFmtProperty(format string) *spec.Schema
StrFmtProperty creates a property for the named string format
func MatchSection ¶
func MatchSection(compiled []Element, sections []string) (bool, bool, map[string]string)
func ObjectProperty ¶
func ObjectProperty() *spec.Schema
func ParsePathTokens ¶
func ParsePathTokens(path string) []string
Types ¶
type Builder ¶
type Builder struct {
InterfaceBuildOption InterfaceBuildOption
Definitions map[string]spec.Schema
}
func NewBuilder ¶
func NewBuilder(interfaceOption InterfaceBuildOption) *Builder
func (*Builder) BuildSchema ¶
func (b *Builder) BuildSchema(v reflect.Value) *spec.Schema
type CompileError ¶
type CompileError struct {
Pattern string
Position int
Rune rune
Message string
}
type Element ¶
type Element struct {
// contains filtered or unexported fields
}
func CompileSection ¶
func CompileSection(pattern string) ([]Element, error)
func MustCompileSection ¶
func MustCompileSection(pattern string) []Element
type ElementKind ¶
type ElementKind string
const (
ElementKindNone ElementKind = ""
ElementKindConst ElementKind = "const"
ElementKindVariable ElementKind = "{}"
ElementKindStar ElementKind = "*"
ElementKindSplit ElementKind = "/"
)
type Group ¶
type Group struct {
// contains filtered or unexported fields
}
func (*Group) AddSubGroup ¶
func (g *Group) AddSubGroup(groups ...*Group) *Group
func (*Group) Parameters ¶
func (g *Group) Parameters(params ...Param) *Group
type InterfaceBuildOption ¶
type InterfaceBuildOption string
const (
InterfaceBuildOptionDefault InterfaceBuildOption = "" // default as an 'object{}'
InterfaceBuildOptionOverride InterfaceBuildOption = "override" // override using interface's value if exist
InterfaceBuildOptionIgnore InterfaceBuildOption = "ignore" // ignore interface field
InterfaceBuildOptionMerge InterfaceBuildOption = "merge" // anyOf 'object{}' type and interface's value type
)
type Param ¶
type Param struct {
Name string
Kind ParamKind
Type string
IsOptional bool
Description string
Example interface{}
}
func BodyParameter ¶
func BodyParameter(name string, value interface{}) Param
func FormParameter ¶
func FormParameter(name string, description string) Param
func PathParameter ¶
func PathParameter(name string, description string) Param
func QueryParameter ¶
func QueryParameter(name string, description string) Param
type ParamKind ¶
type ParamKind string
const (
ParamKindPath ParamKind = "path"
ParamKindQuery ParamKind = "query"
ParamKindHeader ParamKind = "header"
ParamKindForm ParamKind = "form"
ParamKindBody ParamKind = "body"
)
type PathTokens ¶
type PathTokens struct {
Tokens []string
}
type ResponseMeta ¶
type ResponseMeta struct {
Code int
Headers map[string]string
Body interface{}
Description string
}
type Route ¶
type Route struct {
Summary string
Path string
Method string
Func Function
Tags []string
Consumes []string
Produces []string
Params []Param
Responses []ResponseMeta
Properties map[string]interface{}
}
func (*Route) Accept ¶ added in v1.22.0
func (n *Route) Accept(mime ...string) *Route
Accept types of all the responses
func (*Route) ContentType ¶ added in v1.22.0
func (n *Route) ContentType(mime ...string) *Route
ContentType of all available responses type
func (*Route) Parameters ¶
func (n *Route) Parameters(params ...Param) *Route
func (*Route) SetProperty ¶
func (n *Route) SetProperty(k string, v interface{}) *Route
type Router ¶
type Router struct {
Notfound gin.HandlerFunc
// contains filtered or unexported fields
}
func (*Router) MustRegister ¶
func (m *Router) MustRegister(method, path string, handler gin.HandlerFunc)
type SchemaBuildFunc ¶
type SchemaBuildFunc func(v reflect.Value) *spec.Schema
type ServeMux ¶
type ServeMux struct {
// contains filtered or unexported fields
}
ServeMux is a http.ServeMux like library,but support path variable
func NewServeMux ¶
func NewServeMux() *ServeMux
func (*ServeMux) HandlerFunc ¶
func (mux *ServeMux) HandlerFunc(pattern string, handler func(w http.ResponseWriter, r *http.Request))
type SwaggerBuilder ¶
type SwaggerBuilder struct {
// contains filtered or unexported fields
}
type Tree ¶
type Tree struct {
Group *Group
RouteUpdateFunc func(r *Route) // can update route setting before build
}
func (*Tree) AddToWebService ¶
func (t *Tree) AddToWebService(ws *restful.WebService)