fastapi

package module
v0.2.0-beta Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2023 License: MIT Imports: 24 Imported by: 3

README

FastApi-Golang

  • FastApiGolang实现;
  • 基于Fiber;

Usage:

go get https://github.com/Chendemo12/fastapi
查看在线文档
# 安装godoc
go install golang.org/x/tools/cmd/godoc@latest
godoc -http=:6060

# 或:pkgsite 推荐
go install golang.org/x/pkgsite/cmd/pkgsite@latest
cd fastapi-go/
pkgsite -http=:6060 -list=false
# 浏览器打开:http://127.0.0.1:6060/github.com/Chendemo12/fastapi
struct内存对齐
go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@latest

fieldalignment -fix ./... 
打包静态资源文件
# 安装工具
go get -u github.com/go-bindata/go-bindata/...
go install github.com/go-bindata/go-bindata/...

# 下载资源文件
#https://fastapi.tiangolo.com/img/favicon.png
#https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css
#https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js
#https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js

# 打包资源文件到openapi包
go-bindata -o openapi/css.go --pkg openapi internal/static/...

Guide:

面向对象式路由:GroupRouter
package main

type QueryParamRouter struct {
	BaseRouter
}

func (r *QueryParamRouter) Prefix() string { return "/api/query-param" }

func (r *QueryParamRouter) IntQueryParamGet(c *Context, age int) (int, error) {
	return age, nil
}

  1. 对于请求参数
  • 识别函数参数作为查询参数, (GET/DELETE/POST/PUT/PATCH)。

    由于反射限制,无法识别函数参数名称,因此显示在文档上的参数名为随机分配的,推荐通过结构体实现。

  • 将最后一个结构体解析为查询参数, (GET/DELETE), 推荐。

    package main
    
    type LogonQuery struct {
        Father string `query:"father" validate:"required" description:"姓氏"` // 必选查询参数
        Name   string `query:"name" description:"姓名"`                       // 可选查询参数
    }
    
  • 将最后一个结构体解析为请求体, (POST/PUT/PATCH)。

  • 将除最后一个参数解析为查询参数(包含结构体查询参数), (POST/PUT/PATCH)。

  • 允许重载API路由以支持路径参数, (GET/DELETE/POST/PUT/PATCH)。

  • 在任何时候,通过添加方法SchemaDesc() string以为模型添加文本说明

一些常用的API

Documentation

Overview

Package fastapi FastApi-Python 的Golang实现

其提供了类似于FastAPI的API设计,并提供了接口文档自动生成、请求体自动校验和返回值自动序列化等使用功能;

Index

Constants

View Source
const (
	FirstInParamOffset       = 1                      // 第一个有效参数的索引位置,由于结构体接收器处于第一位置
	FirstCustomInParamOffset = FirstInParamOffset + 1 // 第一个自定义参数的索引位置
	FirstOutParamOffset      = 0
	LastOutParamOffset       = 1 // 最后一个返回值参数的索引位置
	OutParamNum              = 2
)
View Source
const (
	FirstInParamName = "Context" // 第一个入参名称
	LastOutParamName = "error"   // 最后一个出参名称
)
View Source
const (
	ModelNotDefine     = "Data model is undefined"
	ModelNotMatch      = "Value type mismatch"
	ModelCannotString  = "The return value cannot be a string"
	ModelCannotNumber  = "The return value cannot be a number"
	ModelCannotInteger = "The return value cannot be a integer"
	ModelCannotBool    = "The return value cannot be a boolean"
	ModelCannotArray   = "The return value cannot be a array"
	PathPsIsEmpty      = "Path must not be empty"
	QueryPsIsEmpty     = "Query must not be empty"
)
View Source
const (
	Version   = "0.2.0"
	Copyright = "chendemo12"
	Website   = "https://github.com/Chendemo12"
)
View Source
const HotSwitchSigint = 30

HotSwitchSigint 默认热调试开关

View Source
const HttpMethodMinimumLength = len(http.MethodGet)
View Source
const WebsocketMethod = "WS"

Variables

View Source
var IllegalLastInParamType = append(openapi.IllegalRouteParamType, reflect.Ptr)

IllegalLastInParamType 非法的请求体类型, 不支持指针的指针

IllegalResponseType 非法的返回值类型, 不支持指针的指针

View Source
var (
	ReflectObjectType = utils.ReflectObjectType
)

Functions

func LazyInit added in v0.2.0

func LazyInit()

func Logger added in v0.2.0

func Logger() logger.Iface

func ParseJsoniterError added in v0.2.0

func ParseJsoniterError(err error, loc openapi.RouteParamType, objName string) *openapi.ValidationError

ParseJsoniterError 将jsoniter 的反序列化错误转换成 接口错误类型

func ParseValidatorError added in v0.2.0

func ParseValidatorError(err error, loc openapi.RouteParamType, objName string) []*openapi.ValidationError

ParseValidatorError 解析Validator的错误消息 如果不存在错误,则返回nil; 如果 err 是 validator.ValidationErrors 的错误, 则解析并返回详细的错误原因,反之则返回模糊的错误原因

func ReleaseResponse added in v0.2.0

func ReleaseResponse(resp *Response)

Types

type BaseGroupRouter added in v0.2.0

type BaseGroupRouter struct {
	BaseRouter
	Title   string
	Version string
	Desc    string
	Debug   bool
}

func (*BaseGroupRouter) Description added in v0.2.0

func (r *BaseGroupRouter) Description() map[string]string

func (*BaseGroupRouter) GetDebug

func (r *BaseGroupRouter) GetDebug(c *Context) (bool, error)

func (*BaseGroupRouter) GetDescription

func (r *BaseGroupRouter) GetDescription(c *Context) (string, error)

func (*BaseGroupRouter) GetHeartbeat

func (r *BaseGroupRouter) GetHeartbeat(c *Context) (string, error)

func (*BaseGroupRouter) GetTitle

func (r *BaseGroupRouter) GetTitle(c *Context) (string, error)

func (*BaseGroupRouter) GetVersion

func (r *BaseGroupRouter) GetVersion(c *Context) (string, error)

func (*BaseGroupRouter) PathSchema added in v0.2.0

func (r *BaseGroupRouter) PathSchema() pathschema.RoutePathSchema

func (*BaseGroupRouter) Prefix added in v0.2.0

func (r *BaseGroupRouter) Prefix() string

func (*BaseGroupRouter) Summary added in v0.2.0

func (r *BaseGroupRouter) Summary() map[string]string

func (*BaseGroupRouter) Tags added in v0.2.0

func (r *BaseGroupRouter) Tags() []string

type BaseModel

type BaseModel struct{}

BaseModel 基本数据模型, 对于上层的路由定义其请求体和响应体都应为继承此结构体的结构体 在 OpenApi 文档模型中,此模型的类型始终为 "object" 对于 BaseModel 其字段仍然可能会是 BaseModel

func (*BaseModel) IsRequired added in v0.2.0

func (b *BaseModel) IsRequired() bool

func (*BaseModel) SchemaDesc added in v0.2.0

func (b *BaseModel) SchemaDesc() string

SchemaDesc 结构体文档注释

func (*BaseModel) SchemaType added in v0.2.0

func (b *BaseModel) SchemaType() openapi.DataType

SchemaType 模型类型

type BaseRouter added in v0.2.0

type BaseRouter struct {
}

BaseRouter (面向对象式)路由组基类 需实现 GroupRouter 接口

其中以 Get,Post,Delete,Patch,Put 字符串(不区分大小写)开头或结尾并以 (XXX, error)形式为返回值的方法会被作为路由处理 其url的确定按照 RoutePathSchema 接口进行解析。

对于作为路由的方法签名有如下要求:

1:参数:

	第一个参数必须为 *Context
	如果有多个参数, 除第一个参数和最后一个参数允许为结构体外, 其他参数必须为基本数据类型
	对于Get/Delete:除第一个参数外的其他参数均被作为查询参数处理,如果为一个结构体,则对结构体字段进行解析并确定是否必选,如果为基本类型则全部为可选参数;
	对于Post/Patch/Put: 其最后一个参数必须为一个 struct指针,此参数会作为请求体进行处理,其他参数则=全部为可选的查询参数

2:返回值

	有且仅有2个返回值 (XXX, error)
	其中XXX会作为响应体模型,若error!=nil则返回错误; 如果返回值XXX=nil则无响应体

对于上述参数和返回值XXX,其数据类型不能是 接口,函数,通道,指针的指针;
只能是以下类型:~int, ~float, ~string, ~slice, ~struct, ~map, 结构体指针;
对于结构体类型,最好实现了 SchemaIface 接口

func (*BaseRouter) Description

func (g *BaseRouter) Description() map[string]string

func (*BaseRouter) Path

func (g *BaseRouter) Path() map[string]string

func (*BaseRouter) PathSchema

func (g *BaseRouter) PathSchema() pathschema.RoutePathSchema

func (*BaseRouter) Prefix

func (g *BaseRouter) Prefix() string

func (*BaseRouter) Summary

func (g *BaseRouter) Summary() map[string]string

func (*BaseRouter) Tags

func (g *BaseRouter) Tags() []string

type BoolBindMethod added in v0.2.0

type BoolBindMethod struct {
	Title string `json:"title,omitempty"`
}

func (*BoolBindMethod) Marshal added in v0.2.0

func (m *BoolBindMethod) Marshal(obj any) ([]byte, error)

func (*BoolBindMethod) Name added in v0.2.0

func (m *BoolBindMethod) Name() string

func (*BoolBindMethod) New added in v0.2.0

func (m *BoolBindMethod) New() any

New 返回 bool类型而零值false

func (*BoolBindMethod) Unmarshal added in v0.2.0

func (m *BoolBindMethod) Unmarshal(stream []byte, obj any) (ves []*openapi.ValidationError)

func (*BoolBindMethod) Validate added in v0.2.0

func (m *BoolBindMethod) Validate(ctx context.Context, data any) (any, []*openapi.ValidationError)

Validate data 为字符串类型

type Config added in v0.1.4

type Config struct {
	Logger                         logger.Iface `json:"-" description:"日志"`
	Version                        string       `json:"version,omitempty" description:"APP版本号"`
	Description                    string       `json:"description,omitempty" description:"APP描述"`
	Title                          string       `json:"title,omitempty" description:"APP标题,也是日志文件名"`
	ShutdownTimeout                int          `json:"shutdown_timeout,omitempty" description:"平滑关机,单位秒"`
	DisableSwagAutoCreate          bool         `json:"disable_swag_auto_create,omitempty" description:"禁用自动文档"`
	StopImmediatelyWhenErrorOccurs bool         `json:"stopImmediatelyWhenErrorOccurs" description:"是否在遇到错误字段时立刻停止校验"`
	Debug                          bool         `json:"debug,omitempty" description:"调试模式"`
}

type Context

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

Context 路由上下文信息, 也是钩子函数的操作句柄

此结构体内包含了响应体 Response 以减少在路由处理过程中的内存分配和复制

注意: 当一个路由被执行完毕时, 路由函数中的 Context 将被立刻释放回收, 因此在return之后对
Context 的任何引用都是不对的, 若需在return之后监听 Context.DisposableCtx() 则应该显式的复制或派生

func (*Context) AnyResponse

func (c *Context) AnyResponse(statusCode int, content any, contentType ...string) *Response

AnyResponse 自定义响应体,响应体可是任意类型 (不校验返回值)

@param	statusCode	int		响应状态码
@param	content		any		响应体
@param	contentType	[]string	响应头MIME, 默认值为“application/json; charset=utf-8”
@return	resp *Response response返回体

func (*Context) ContentType added in v0.2.0

func (c *Context) ContentType(contentType string)

ContentType 允许路由组路由函数修改响应MIME 由于路由组路由函数 GroupRouteHandler 签名的限制;其返回ContentType默认为"application/json; charset=utf-8" 允许通过此方法进行修改

func (*Context) Deadline

func (c *Context) Deadline() (deadline time.Time, ok bool)

func (*Context) DisposableCtx

func (c *Context) DisposableCtx() context.Context

DisposableCtx 针对此次请求的唯一context, 当路由执行完毕返回时,将会自动关闭 <如果 ContextAutomaticDerivationDisabled = true 则异常> 为每一个请求创建一个新的 context.Context 其代价是非常高的,因此允许通过设置关闭此功能

@return	context.Context 唯一context

func (*Context) Done

func (c *Context) Done() <-chan struct{}

Done 监听 DisposableCtx 是否完成退出 <如果 ContextAutomaticDerivationDisabled = true 则异常>

@return	chan struct{} 是否退出

func (*Context) Err

func (c *Context) Err() error

func (*Context) ErrorResponse

func (c *Context) ErrorResponse(content any) *Response

ErrorResponse 返回一个服务器错误 (不校验返回值)

@param	content	any	错误消息
@return	resp *Response response返回体

func (*Context) F

func (c *Context) F(s ...string) string

F 合并字符串

func (*Context) FileResponse

func (c *Context) FileResponse(filepath string) *Response

FileResponse 返回值为文件对象,如:照片视频文件流等, 若文件不存在,则状态码置为404 (不校验返回值)

@param	filepath	string	文件路径
@return	resp *Response response返回体

func (*Context) HTMLResponse

func (c *Context) HTMLResponse(statusCode int, content []byte) *Response

HTMLResponse 返回一段HTML文本 (不校验返回值)

@param	statusCode	int		响应状态码
@param	content		string	HTML文本字符串
@return	resp *Response response返回体

func (*Context) JSONResponse

func (c *Context) JSONResponse(statusCode int, content any) *Response

JSONResponse 仅支持可以json序列化的响应体 (校验返回值)

对于结构体类型: 其返回值为序列化后的json 对于基本数据类型: 其返回值为实际数值

@param	statusCode	int	响应状态码
@param	content		any	可以json序列化的类型
@return	resp *Response response返回体

func (*Context) Logger

func (c *Context) Logger() logger.Iface

Logger 获取注册的日志句柄

func (*Context) Marshal

func (c *Context) Marshal(obj any) ([]byte, error)

func (*Context) MuxContext added in v0.2.0

func (c *Context) MuxContext() MuxContext

MuxContext 获取web引擎的上下文

func (*Context) OKResponse

func (c *Context) OKResponse(content any) *Response

OKResponse 返回状态码为200的 JSONResponse (校验返回值)

@param	content	any	可以json序列化的类型
@return	resp *Response response返回体

func (*Context) PathField added in v0.2.0

func (c *Context) PathField(name string, undefined ...string) string

PathField 获取路径参数 对于已经在路由处定义的路径参数,首先从 Context.pathFields 内部读取; 对于没有定义的其他查询参数则调用低层 MuxContext 进行解析

func (*Context) Query added in v0.2.0

func (c *Context) Query(name string, undefined ...string) any

Query 获取查询参数 对于已经在路由处定义的查询参数,首先从 Context.queryFields 内部读取 对于没有定义的其他查询参数则调用低层 MuxContext 进行解析

对于路由处定义的查询参数,参数类型会按照以下规则进行转换:

int 	=> int64
uint 	=> uint64
float 	=> float64
string 	=> string
bool 	=> bool

func (*Context) Service

func (c *Context) Service() *Service

Service 获取 Wrapper 的 Service 服务依赖信息

@return	Service 服务依赖信息

func (*Context) Status added in v0.2.0

func (c *Context) Status(code int)

Status 允许路由组路由函数在error=nil时修改响应状态码 由于路由组路由函数 GroupRouteHandler 签名的限制;当error=nil时状态码默认为500,error!=nil时默认为200 允许通过此方法进行修改

func (*Context) StreamResponse

func (c *Context) StreamResponse(reader io.Reader, mime ...string) *Response

StreamResponse 返回值为字节流对象 (不校验返回值)

@param	reader	io.Reader	字节流
@param	mime	string		返回头媒体资源类型信息,	缺省则为	"text/plain"
@return	resp *Response response返回体

func (*Context) StringResponse

func (c *Context) StringResponse(content string) *Response

StringResponse 返回值为字符串对象 (不校验返回值)

@param	content	string	字符串文本
@return	resp *Response response返回体

func (*Context) Unmarshal

func (c *Context) Unmarshal(data []byte, v interface{}) error

func (*Context) Validator

func (c *Context) Validator() *validator.Validate

Validator 获取请求体验证器

func (*Context) Value

func (c *Context) Value(key any) any

type Ctx

type Ctx = Context

type Dict

type Dict = map[string]any // python.Dict

type Event

type Event struct {
	Fc   func()
	Type EventKind // 事件类型:startup 或 shutdown
}

Event 事件

type EventKind

type EventKind string

EventKind 事件类型

const (
	StartupEvent  EventKind = "startup"
	ShutdownEvent EventKind = "shutdown"
)

type FastApi

type FastApi = Wrapper

type Finder added in v0.2.0

type Finder[T RouteIface] interface {
	Init(items []T) // 通过固定元素初始化查找器
	Get(id string) (T, bool)
	Range(fn func(item T) bool)
}

Finder 固定元素的查找器 用于从一个固定的元素集合内依据唯一标识来快速查找元素

func DefaultFinder added in v0.2.0

func DefaultFinder() Finder[RouteIface]

type FloatBindMethod added in v0.2.0

type FloatBindMethod struct {
	Title string       `json:"title,omitempty"`
	Kind  reflect.Kind `json:"kind,omitempty"`
}

func (*FloatBindMethod) Marshal added in v0.2.0

func (m *FloatBindMethod) Marshal(obj any) ([]byte, error)

func (*FloatBindMethod) Name added in v0.2.0

func (m *FloatBindMethod) Name() string

func (*FloatBindMethod) New added in v0.2.0

func (m *FloatBindMethod) New() any

New 返回float64的零值

func (*FloatBindMethod) Unmarshal added in v0.2.0

func (m *FloatBindMethod) Unmarshal(stream []byte, obj any) (ves []*openapi.ValidationError)

func (*FloatBindMethod) Validate added in v0.2.0

func (m *FloatBindMethod) Validate(ctx context.Context, data any) (any, []*openapi.ValidationError)

Validate 验证字符串data是否是一个float类型,data 应为string类型

type GenericRoute added in v0.2.0

type GenericRoute[T openapi.ModelSchema] struct {
	// contains filtered or unexported fields
}

GenericRoute 泛型路由定义

func Delete added in v0.2.0

func Delete[T openapi.ModelSchema](path string, handler func(c *Context, query T) *Response, opt ...Option) *GenericRoute[T]

func Get added in v0.2.0

func Get[T openapi.ModelSchema](path string, handler func(c *Context, query T) *Response, opt ...Option) *GenericRoute[T]

Get TODO Future-231126.5: 泛型路由注册

func Patch added in v0.2.0

func Patch[T openapi.ModelSchema](path string, handler func(c *Context, req T) *Response, opt ...Option) *GenericRoute[T]

func Post added in v0.2.0

func Post[T openapi.ModelSchema](path string, handler func(c *Context, req T) *Response, opt ...Option) *GenericRoute[T]

func (*GenericRoute[T]) Call

func (r *GenericRoute[T]) Call(ctx *Context)

func (*GenericRoute[T]) HasStructQuery

func (r *GenericRoute[T]) HasStructQuery() bool

func (*GenericRoute[T]) Id

func (r *GenericRoute[T]) Id() string

func (*GenericRoute[T]) Init

func (r *GenericRoute[T]) Init() (err error)

func (*GenericRoute[T]) NewInParams

func (r *GenericRoute[T]) NewInParams(ctx *Context) []reflect.Value

func (*GenericRoute[T]) NewRequestModel

func (r *GenericRoute[T]) NewRequestModel() any

func (*GenericRoute[T]) NewStructQuery

func (r *GenericRoute[T]) NewStructQuery() any

func (*GenericRoute[T]) QueryBinders

func (r *GenericRoute[T]) QueryBinders() []*ParamBinder

func (*GenericRoute[T]) RequestBinders

func (r *GenericRoute[T]) RequestBinders() *ParamBinder

func (*GenericRoute[T]) ResponseBinder

func (r *GenericRoute[T]) ResponseBinder() *ParamBinder

func (*GenericRoute[T]) ResponseValidate

func (r *GenericRoute[T]) ResponseValidate(c *Context, stopImmediately bool) []*openapi.ValidationError

func (*GenericRoute[T]) RouteType

func (r *GenericRoute[T]) RouteType() RouteType

func (*GenericRoute[T]) Scan

func (r *GenericRoute[T]) Scan() (err error)

func (*GenericRoute[T]) ScanInner

func (r *GenericRoute[T]) ScanInner() (err error)

func (*GenericRoute[T]) Swagger

func (r *GenericRoute[T]) Swagger() *openapi.RouteSwagger

type GenericRouteHandler added in v0.2.0

type GenericRouteHandler func(c *Context, param any) *Response

GenericRouteHandler 泛型路由函数定义,其中 param 定义为实际的泛型类型

type GenericRouterMeta added in v0.2.0

type GenericRouterMeta[T openapi.ModelSchema] struct {
	// contains filtered or unexported fields
}

GenericRouterMeta 统一记录所有的泛型路由

type GroupRoute added in v0.2.0

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

GroupRoute 路由组路由定义

func NewGroupRoute added in v0.2.0

func NewGroupRoute(swagger *openapi.RouteSwagger, method reflect.Method, group *GroupRouterMeta) *GroupRoute

func (*GroupRoute) Call added in v0.2.0

func (r *GroupRoute) Call(ctx *Context)

Call 调用API, 并将响应结果写入 Response 内

func (*GroupRoute) HasStructQuery added in v0.2.0

func (r *GroupRoute) HasStructQuery() bool

func (*GroupRoute) Id added in v0.2.0

func (r *GroupRoute) Id() string

func (*GroupRoute) Init added in v0.2.0

func (r *GroupRoute) Init() (err error)

func (*GroupRoute) NewInParams added in v0.2.0

func (r *GroupRoute) NewInParams(ctx *Context) []reflect.Value

func (*GroupRoute) NewRequestModel added in v0.2.0

func (r *GroupRoute) NewRequestModel() any

func (*GroupRoute) NewStructQuery added in v0.2.0

func (r *GroupRoute) NewStructQuery() any

NewStructQuery 构造一个新的结构体查询参数实例

func (*GroupRoute) QueryBinders added in v0.2.0

func (r *GroupRoute) QueryBinders() []*ParamBinder

QueryBinders 查询参数校验方法

func (*GroupRoute) RequestBinders added in v0.2.0

func (r *GroupRoute) RequestBinders() *ParamBinder

func (*GroupRoute) ResponseBinder added in v0.2.0

func (r *GroupRoute) ResponseBinder() *ParamBinder

func (*GroupRoute) ResponseValidate added in v0.2.0

func (r *GroupRoute) ResponseValidate(c *Context, stopImmediately bool) []*openapi.ValidationError

ResponseValidate 仅校验“200的JSONResponse”

func (*GroupRoute) RouteType added in v0.2.0

func (r *GroupRoute) RouteType() RouteType

func (*GroupRoute) Scan added in v0.2.0

func (r *GroupRoute) Scan() (err error)

func (*GroupRoute) ScanInner added in v0.2.0

func (r *GroupRoute) ScanInner() (err error)

ScanInner 解析内部 openapi.RouteSwagger 数据

func (*GroupRoute) Swagger added in v0.2.0

func (r *GroupRoute) Swagger() *openapi.RouteSwagger

type GroupRouteHandler added in v0.2.0

type GroupRouteHandler func(c *Context, params ...any) (any, error)

GroupRouteHandler 路由组路由函数签名,其中any可以是具体的类型,但不应该是 Response

type GroupRouter added in v0.2.0

type GroupRouter interface {
	// Prefix 路由组前缀,无需考虑是否以/开头或结尾
	// 如果为空则通过 PathSchema 方案进行格式化
	Prefix() string
	// Tags 标签,如果为空则设为结构体名称的大驼峰形式,去掉可能存在的http方法名
	Tags() []string
	// PathSchema 路由解析规则,对路由前缀和路由地址都有效
	PathSchema() pathschema.RoutePathSchema
	// Summary 允许对单个方法路由的文档摘要信息进行定义
	// 方法名:摘要信息
	Summary() map[string]string
	// Description 方法名:描述信息
	Description() map[string]string
	// Path 允许对方法的路由进行重载, 方法名:相对路由
	// 由于以函数名确定方法路由的方式暂无法支持路径参数, 因此可通过此方式来定义路径参数
	// 但是此处定义的路由不应该包含查询参数
	// 路径参数以:开头, 查询参数以?开头
	Path() map[string]string
}

GroupRouter 结构体路由组定义 用法:首先实现此接口,然后通过调用 Wrapper.IncludeRoute 方法进行注册绑定

func NewBaseRouter

func NewBaseRouter(conf Config) GroupRouter

NewBaseRouter 用于获取后端服务基本信息的路由组

# Usage

router := NewBaseRouter(Config{})
app.IncludeRouter(router)

type GroupRouterMeta added in v0.2.0

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

GroupRouterMeta 反射构建路由组的元信息

func NewGroupRouteMeta added in v0.2.0

func NewGroupRouteMeta(router GroupRouter) *GroupRouterMeta

NewGroupRouteMeta 构建一个路由组的主入口

func (*GroupRouterMeta) Init added in v0.2.0

func (r *GroupRouterMeta) Init() (err error)

func (*GroupRouterMeta) Routes added in v0.2.0

func (r *GroupRouterMeta) Routes() []*GroupRoute

func (*GroupRouterMeta) Scan added in v0.2.0

func (r *GroupRouterMeta) Scan() (err error)

func (*GroupRouterMeta) ScanInner added in v0.2.0

func (r *GroupRouterMeta) ScanInner() (err error)

ScanInner 处理内部路由 GroupRoute 的文档等数据

func (*GroupRouterMeta) String added in v0.2.0

func (r *GroupRouterMeta) String() string

type H

type H = map[string]any // gin.H

type IndexFinder added in v0.2.0

type IndexFinder[T RouteIface] struct {
	// contains filtered or unexported fields
}

func (*IndexFinder[T]) Get added in v0.2.0

func (f *IndexFinder[T]) Get(id string) (T, bool)

func (*IndexFinder[T]) Init added in v0.2.0

func (f *IndexFinder[T]) Init(items []T)

func (*IndexFinder[T]) Range added in v0.2.0

func (f *IndexFinder[T]) Range(fn func(item T) bool)

Range if false returned, for-loop will stop

type IntBindMethod added in v0.2.0

type IntBindMethod struct {
	Title   string       `json:"title,omitempty"`
	Kind    reflect.Kind `json:"kind,omitempty"`
	Maximum int64        `json:"maximum,omitempty"`
	Minimum int64        `json:"minimum,omitempty"`
}

IntBindMethod 有符号数字验证

func (*IntBindMethod) Marshal added in v0.2.0

func (m *IntBindMethod) Marshal(obj any) ([]byte, error)

func (*IntBindMethod) Name added in v0.2.0

func (m *IntBindMethod) Name() string

func (*IntBindMethod) New added in v0.2.0

func (m *IntBindMethod) New() any

New 返回int的零值

func (*IntBindMethod) Unmarshal added in v0.2.0

func (m *IntBindMethod) Unmarshal(stream []byte, obj any) (ves []*openapi.ValidationError)

func (*IntBindMethod) Validate added in v0.2.0

func (m *IntBindMethod) Validate(ctx context.Context, data any) (any, []*openapi.ValidationError)

type JsonBindMethod added in v0.2.0

type JsonBindMethod[T any] struct {
	Title          string `json:"title,omitempty"`
	RouteParamType openapi.RouteParamType
}

JsonBindMethod json数据类型验证器,适用于泛型路由

func (*JsonBindMethod[T]) Marshal added in v0.2.0

func (m *JsonBindMethod[T]) Marshal(obj T) ([]byte, error)

func (*JsonBindMethod[T]) Name added in v0.2.0

func (m *JsonBindMethod[T]) Name() string

func (*JsonBindMethod[T]) New added in v0.2.0

func (m *JsonBindMethod[T]) New() any

func (*JsonBindMethod[T]) Unmarshal added in v0.2.0

func (m *JsonBindMethod[T]) Unmarshal(stream []byte, obj T) (ves []*openapi.ValidationError)

func (*JsonBindMethod[T]) Validate added in v0.2.0

func (m *JsonBindMethod[T]) Validate(ctx context.Context, data T) (T, []*openapi.ValidationError)

type MiddlewareHandle added in v0.2.0

type MiddlewareHandle func(c *Context) error

MiddlewareHandle 中间件函数

由于 Wrapper 的核心实现类似于装饰器,而非常规的中间件,因此应当通过 Wrapper 来定义中间件, 以避免通过 MuxWrapper 注册的中间件对 Wrapper 产生副作用; 此处中间件有校验前中间件和校验后中间件,分别通过 Wrapper.UsePrevious 和 Wrapper.UseAfter 注册; 当请求参数校验失败时不会执行 Wrapper.UseAfter 中间件, 请求参数会在 Wrapper.UsePrevious 执行完成之后被触发; 如果中间件要终止后续的流程,应返回 error, 错误消息会作为消息体返回给客户端, 响应状态码默认为400,可通过 Context.Status 进行修改;

type ModelBindMethod added in v0.2.0

type ModelBindMethod interface {
	Name() string // 名称
	// Validate
	// 校验方法,对于响应首先校验,然后在 Marshal;对于请求,首先 Unmarshal 然后再校验
	// 对于不需要ctx参数的校验方法可默认设置为nil
	// data 为需要验证的数据模型,如果验证通过,则第一个返回值为做了类型转换的data
	Validate(ctx context.Context, data any) (any, []*openapi.ValidationError)
	Marshal(obj any) ([]byte, error)                                   // 序列化方法,通过 ContentType 确定响应体类型
	Unmarshal(stream []byte, obj any) (ves []*openapi.ValidationError) // 反序列化方法,通过 "http:header:Content-Type" 推断内容类型
	New() any                                                          // 创建一个新实例
}

func InferBinderMethod

func InferBinderMethod(param openapi.SchemaIface, prototypeKind reflect.Kind, modelType openapi.RouteParamType) ModelBindMethod

InferBinderMethod 利用反射推断参数的校验器

type MuxContext added in v0.2.0

type MuxContext interface {
	Method() string                                // [重要方法]获得当前请求方法,取为为 http.MethodGet, http.MethodPost 等
	Path() string                                  // [重要方法]获的当前请求的路由模式,而非请求Url
	ContentType() string                           // Content-Type
	Header(key, value string)                      // 添加响应头
	Cookie(name string) (string, error)            // 读取cookie
	Query(key string, undefined ...string) string  // 解析查询参数
	Params(key string, undefined ...string) string // 解析路径参数

	BodyParser(obj any) error       // 反序列化到 obj 上,作用等同于Unmarshal
	Validate(obj any) error         // 校验请求体, error应为 validator.ValidationErrors 类型
	ShouldBind(obj any) error       // 反序列化并校验请求体 = BodyParser + Validate, error 应为validator.ValidationErrors 类型
	BindQuery(obj any) error        // 绑定请求参数到 obj 上, error应为 validator.ValidationErrors 类型
	ShouldBindNotImplemented() bool // mux 没有实现 ShouldBind 方法, 此情况下会采用替代实现
	BindQueryNotImplemented() bool  // mux 没有实现 BindQuery 方法, 此情况下会采用替代实现

	Set(key string, value any)                     // Set用于存储专门用于此上下文的新键/值对,如果以前没有使用c.Keys,它也会延迟初始化它
	Get(key string, defaultValue ...string) string // 从上下文中读取键/值对
	SetCookie(cookie *http.Cookie)                 // 添加cookie
	Redirect(code int, location string) error      // 重定向

	ClientIP() string // ClientIP实现了一个最佳努力算法来返回真实的客户端IP。

	Status(code int)                                               // 设置响应状态码
	Write(p []byte) (int, error)                                   // 写入响应字节流,当此方法执行完毕时应中断后续流程
	SendString(s string) error                                     // 写字符串到响应体,当此方法执行完毕时应中断后续流程
	SendStream(stream io.Reader, size ...int) error                // 写入消息流到响应体
	JSON(code int, data any) error                                 // 写入json响应体
	JSONP(code int, data any) error                                // JSONP 支持
	Render(name string, bind interface{}, layouts ...string) error // 用于返回HTML
	XML(code int, obj any) error                                   // 写入XML
	YAML(code int, obj any) error                                  // 写入YAML
	TOML(code int, obj any) error                                  // 写入TOML
	File(filepath string) error                                    // 返回文件
	FileAttachment(filepath, filename string) error                // 将指定的文件以有效的方式写入主体流, 在客户端,文件通常会以给定的文件名下载
}

MuxContext Web引擎的 Context,例如 fiber.Ctx, gin.Context

type MuxHandler added in v0.2.0

type MuxHandler func(c MuxContext) error

type MuxWrapper added in v0.2.0

type MuxWrapper interface {
	// Listen 启动http server
	Listen(addr string) error
	// ShutdownWithTimeout 优雅关闭
	ShutdownWithTimeout(timeout time.Duration) error
	// BindRoute 注册路由
	BindRoute(method, path string, handler MuxHandler) error
}

MuxWrapper WEB服务器包装器接口 为兼容不同的 server 引擎,需要对其二次包装

type NothingBindMethod added in v0.2.0

type NothingBindMethod struct{}

NothingBindMethod 空实现,用于什么也不做

func (*NothingBindMethod) Marshal added in v0.2.0

func (m *NothingBindMethod) Marshal(obj any) ([]byte, error)

func (*NothingBindMethod) Name added in v0.2.0

func (m *NothingBindMethod) Name() string

func (*NothingBindMethod) New added in v0.2.0

func (m *NothingBindMethod) New() any

func (*NothingBindMethod) Unmarshal added in v0.2.0

func (m *NothingBindMethod) Unmarshal(stream []byte, obj any) (ves []*openapi.ValidationError)

func (*NothingBindMethod) Validate added in v0.2.0

func (m *NothingBindMethod) Validate(ctx context.Context, data any) (any, []*openapi.ValidationError)

type Opt added in v0.1.5

type Opt = Option

type Option added in v0.1.1

type Option struct {
	Summary       string              `json:"summary" description:"摘要描述"`
	ResponseModel openapi.ModelSchema `json:"response_model" description:"响应体模型"`
	RequestModel  openapi.ModelSchema `json:"request_model" description:"请求体模型"`
	Params        openapi.ModelSchema `json:"params" description:"查询参数,结构体"`
	Description   string              `json:"description" description:"路由描述"`
	Tags          []string            `json:"tags" description:"路由标签"`
	Deprecated    bool                `json:"deprecated" description:"是否禁用"`
}

Option 泛型接口定义可选项 NOTICE: 231126 暂不可用

type ParamBinder added in v0.2.0

type ParamBinder struct {
	Method         ModelBindMethod        `json:"-"`
	QModel         *openapi.QModel        `json:"-"`
	RequestModel   *openapi.BaseModelMeta `json:"-"`
	ResponseModel  *openapi.BaseModelMeta `json:"-"`
	Title          string                 `json:"title,omitempty"`
	RouteParamType openapi.RouteParamType
}

ParamBinder 参数验证模型

type Profile added in v0.2.0

type Profile struct {
	Host                               string        `json:"host,omitempty" description:"运行地址"`
	Port                               string        `json:"port,omitempty" description:"运行端口"`
	Title                              string        `json:"title,omitempty" description:"程序名,同时作为日志文件名"`
	Version                            string        `json:"version,omitempty" description:"程序版本号"`
	Description                        string        `json:"description,omitempty" description:"程序描述"`
	ShutdownTimeout                    time.Duration `json:"shutdownTimeout,omitempty" description:"平滑关机,单位秒"`
	Debug                              bool          `json:"debug,omitempty" description:"调试开关"`
	SwaggerDisabled                    bool          `json:"swaggerDisabled,omitempty" description:"禁用自动文档"`
	ContextAutomaticDerivationDisabled bool          `json:"contextAutomaticDerivationDisabled,omitempty" description:"禁用context自动派生"`
	// 默认情况下当请求校验过程遇到错误字段时,仍会继续向下校验其他字段,并最终将所有的错误消息一次性返回给调用方-
	// 当此设置被开启后,在遇到一个错误的参数时,会立刻停止终止流程,直接返回错误消息
	StopImmediatelyWhenErrorOccurs bool `json:"stopImmediatelyWhenErrorOccurs" description:"是否在遇到错误字段时立刻停止校验"`
}

type QueryParamMode added in v0.2.0

type QueryParamMode string

QueryParamMode 查询参数的定义模式,不同模式决定了查询参数的校验方式 对于泛型路由来说,仅存在 结构体查询参数 StructQueryParamMode 一种形式; 对于路由组路由来说,三种形式都存在

const (
	// NoQueryParamMode 不存在查询参数 = 0
	NoQueryParamMode QueryParamMode = "NoQueryParamMode"
	// SimpleQueryParamMode 只有基本数据类型的简单查询参数类型,不包含结构体类型的查询参数 = 1
	SimpleQueryParamMode QueryParamMode = "SimpleQueryParamMode"
	// StructQueryParamMode 以结构体形式定义的查询参数模式 = 4
	StructQueryParamMode QueryParamMode = "StructQueryParamMode"
	// MixQueryParamMode 二种形式都有的混合模式 = 7
	MixQueryParamMode QueryParamMode = "MixQueryParamMode"
)

type Response

type Response struct {
	Content     any          `json:"content" description:"响应体"`
	ContentType string       `json:"-" description:"响应类型,默认为 application/json"`
	Type        ResponseType `json:"-" description:"返回体类型"`
	StatusCode  int          `json:"-" description:"响应状态码"`
}

Response 范型路由返回值 也用于内部直接传递数据,对于 GroupRouteHandler 不应将其作为函数返回值

func AcquireResponse added in v0.2.0

func AcquireResponse() *Response

type ResponseType

type ResponseType int
const (
	CustomResponseType ResponseType = iota + 1
	JsonResponseType
	StringResponseType
	StreamResponseType
	FileResponseType
	ErrResponseType
	HtmlResponseType
)

type RouteIface added in v0.2.0

type RouteIface interface {
	Scanner
	RouteType() RouteType
	Swagger() *openapi.RouteSwagger           // 路由文档
	QueryBinders() []*ParamBinder             // 查询参数的处理接口(查询参数名:处理接口),每一个查询参数都必须绑定一个 ParamBinder
	RequestBinders() *ParamBinder             // 请求体的处理接口,请求体也只有一个
	ResponseBinder() *ParamBinder             // 响应体的处理接口,响应体只有一个
	NewInParams(ctx *Context) []reflect.Value // 创建一个完整的函数入参实例列表, 此方法会在完成请求参数校验 RequestBinders,QueryBinders 之后执行
	NewStructQuery() any                      // 创建一个结构体查询参数实例,对于POST/PATCH/PUT, 即为 NewInParams 的最后一个元素; 对于GET/DELETE则为nil
	NewRequestModel() any                     // 创建一个请求体实例,对于POST/PATCH/PUT, 即为 NewInParams 的最后一个元素; 对于GET/DELETE则为nil
	HasStructQuery() bool                     // 是否存在结构体查询参数,如果存在则会调用 NewStructQuery 获得结构体实例
	Call(ctx *Context)                        // 调用API, 需要将响应结果写入 Response 内
	ResponseValidate(c *Context, stopImmediately bool) []*openapi.ValidationError
	Id() string
}

RouteIface 路由定义 路由组接口定义或泛型接口定义都需实现此接口

type RouteType added in v0.2.0

type RouteType string
const (
	RouteTypeGroup   RouteType = "GroupRoute"
	RouteTypeGeneric RouteType = "GenericRoute"
)

type Scanner added in v0.2.0

type Scanner interface {
	Init() (err error)      // 初始化元数据对象
	Scan() (err error)      // 扫描并初始化自己
	ScanInner() (err error) // 扫描并初始化自己包含的字节点,通过 child.Init() 实现
}

Scanner 元数据接口 Init -> Scan -> ScanInner -> Init 级联初始化

type Service

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

Service Wrapper 全局服务依赖信息 此对象由Wrapper启动时自动创建,此对象不应被修改,组合和嵌入, 但可通过 setUserSVC 接口设置自定义的上下文信息,并在每一个路由钩子函数中可得

func (*Service) Addr

func (s *Service) Addr() string

Addr 绑定地址

@return	string 绑定地址

func (*Service) Done

func (s *Service) Done() <-chan struct{}

Done 监听程序是否退出或正在关闭,仅当程序关闭时解除阻塞

func (*Service) Logger

func (s *Service) Logger() logger.Iface

Logger 获取日志句柄

func (*Service) RootCtx

func (s *Service) RootCtx() context.Context

RootCtx 根 context

@return	context.Context 整个服务的根 context

type SignedInteger added in v0.2.0

type SignedInteger interface {
	~int8 | ~int16 | ~int32 | ~int64 | ~int
}

SignedInteger 有符号数字约束

type SimpleFinder added in v0.2.0

type SimpleFinder[T RouteIface] struct {
	// contains filtered or unexported fields
}

func (*SimpleFinder[T]) Get added in v0.2.0

func (s *SimpleFinder[T]) Get(id string) (T, bool)

func (*SimpleFinder[T]) Init added in v0.2.0

func (s *SimpleFinder[T]) Init(items []T)

func (*SimpleFinder[T]) Range added in v0.2.0

func (s *SimpleFinder[T]) Range(fn func(item T) bool)

Range if false returned, for-loop will stop

type StructQueryBind added in v0.2.0

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

StructQueryBind 结构体查询参数验证器

func (*StructQueryBind) Bind added in v0.2.0

func (m *StructQueryBind) Bind(params map[string]any, obj any) []*openapi.ValidationError

func (*StructQueryBind) Unmarshal added in v0.2.0

func (m *StructQueryBind) Unmarshal(params map[string]any, obj any) *openapi.ValidationError

func (*StructQueryBind) Validate added in v0.2.0

func (m *StructQueryBind) Validate(obj any) []*openapi.ValidationError

type UintBindMethod added in v0.2.0

type UintBindMethod struct {
	Title   string       `json:"title,omitempty"`
	Kind    reflect.Kind `json:"kind,omitempty"`
	Maximum uint64       `json:"maximum,omitempty"`
	Minimum uint64       `json:"minimum,omitempty"`
}

UintBindMethod 无符号数字验证

func (*UintBindMethod) Marshal added in v0.2.0

func (m *UintBindMethod) Marshal(obj any) ([]byte, error)

func (*UintBindMethod) Name added in v0.2.0

func (m *UintBindMethod) Name() string

func (*UintBindMethod) New added in v0.2.0

func (m *UintBindMethod) New() any

New 返回uint的零值

func (*UintBindMethod) Unmarshal added in v0.2.0

func (m *UintBindMethod) Unmarshal(stream []byte, obj any) (ves []*openapi.ValidationError)

func (*UintBindMethod) Validate added in v0.2.0

func (m *UintBindMethod) Validate(ctx context.Context, data any) (any, []*openapi.ValidationError)

type UnsignedInteger added in v0.2.0

type UnsignedInteger interface {
	~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uint
}

UnsignedInteger 无符号数字约束

type Wrapper added in v0.2.0

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

Wrapper 服务对象,本质是一个包装器

func Create added in v0.2.0

func Create(c Config) *Wrapper

Create 创建一个新的 Wrapper 服务 其存在目的在于在同一个应用里创建多个 Wrapper 实例,并允许每个实例绑定不同的服务器实现

getWrapper

func New

func New(c ...Config) *Wrapper

New 实例化一个默认 Wrapper, 此方法与 Create 不能同时使用 与 Create 区别在于:Create 每次都会创建一个新的实例,NewNotStruct 多次调用获得的是同一个实例 语义相当于 __new__ 实现的单例

func (*Wrapper) ActivateHotSwitch added in v0.2.0

func (f *Wrapper) ActivateHotSwitch(s ...int) *Wrapper

ActivateHotSwitch 创建一个热开关,监听信号量(默认值:30),用来改变程序调试开关状态

func (*Wrapper) Config added in v0.2.0

func (f *Wrapper) Config() Config

func (*Wrapper) DisableSwagAutoCreate added in v0.2.0

func (f *Wrapper) DisableSwagAutoCreate() *Wrapper

DisableSwagAutoCreate 禁用文档自动生成

func (*Wrapper) Handler added in v0.2.0

func (f *Wrapper) Handler(ctx MuxContext) error

Handler 路由函数,实现逻辑类似于中间件

路由处理方法(装饰器实现),用于请求体校验和返回体序列化,同时注入全局服务依赖, 此方法接收一个业务层面的路由钩子方法 RouteIface.Call

方法首先会查找路由元信息,如果找不到则直接跳过验证环节,由路由器返回404 反之:

  1. 申请一个 Context, 并初始化请求体、路由参数等
  2. 之后会校验并绑定路由参数(包含路径参数和查询参数)是否正确,如果错误则直接返回422错误,反之会继续序列化并绑定请求体(如果存在)序列化成功之后会校验请求参数正确性,
  3. 校验通过后会调用 RouteIface.Call 并将返回值绑定在 Context 内的 Response 上
  4. 校验返回值,并返回422或将返回值写入到实际的 response

func (*Wrapper) IncludeRouter added in v0.2.0

func (f *Wrapper) IncludeRouter(router GroupRouter) *Wrapper

IncludeRouter 注册一个路由组

@param	router	*Router	路由组

func (*Wrapper) Mux added in v0.2.0

func (f *Wrapper) Mux() MuxWrapper

Mux 获取路由器

func (*Wrapper) OnEvent added in v0.2.0

func (f *Wrapper) OnEvent(kind EventKind, fc func()) *Wrapper

OnEvent 添加事件

@param	kind	事件类型,取值需为	"startup"/"shutdown"
@param	fs		func()		事件

func (*Wrapper) Run added in v0.2.0

func (f *Wrapper) Run(host, port string)

Run 启动服务, 此方法会阻塞运行,因此必须放在main函数结尾 此方法已设置关闭事件和平滑关闭. 当 Interrupt 信号被触发时,首先会关闭 根Context,然后逐步执行“关机事件”,最后调用平滑关闭方法,关闭服务 启动前通过 SetShutdownTimeout 设置"平滑关闭异常时"的最大超时时间

func (*Wrapper) Service

func (f *Wrapper) Service() *Service

Service 获取Wrapper全局服务依赖

func (*Wrapper) SetDescription added in v0.2.0

func (f *Wrapper) SetDescription(description string) *Wrapper

SetDescription 设置APP的详细描述信息

@param	Description	string	详细描述信息

func (*Wrapper) SetLogger added in v0.2.0

func (f *Wrapper) SetLogger(logger logger.Iface) *Wrapper

SetLogger 替换日志句柄,此操作必须在run之前进行

@param	logger	logger.Iface	日志句柄

func (*Wrapper) SetMux added in v0.2.0

func (f *Wrapper) SetMux(mux MuxWrapper) *Wrapper

SetMux 设置路由器,必须在启动之前设置

func (*Wrapper) SetShutdownTimeout added in v0.2.0

func (f *Wrapper) SetShutdownTimeout(timeout int) *Wrapper

SetShutdownTimeout 修改关机前最大等待时间

@param	timeout	in	修改关机前最大等待时间,	单位秒

func (*Wrapper) Shutdown added in v0.2.0

func (f *Wrapper) Shutdown()

Shutdown 平滑关闭

func (*Wrapper) Use added in v0.2.0

func (f *Wrapper) Use(middleware ...MiddlewareHandle) *Wrapper

Use 添加一个中间件, 数据校验后中间件

func (*Wrapper) UseAfter added in v0.2.0

func (f *Wrapper) UseAfter(middleware ...MiddlewareHandle) *Wrapper

UseAfter 添加一个校验后中间件, 此中间件会在:请求参数校验后-路由函数调用前执行

func (*Wrapper) UsePrevious added in v0.2.0

func (f *Wrapper) UsePrevious(middleware ...MiddlewareHandle) *Wrapper

UsePrevious 添加一个校验前中间件,此中间件会在:请求参数校验前调用

Directories

Path Synopsis
middleware
Code generated by go-bindata.
Code generated by go-bindata.

Jump to

Keyboard shortcuts

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