elton

package module
v2.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 26 Imported by: 0

README

Elton

license Build Status

Alt

Elton的实现参考了koa以及echo,中间件的调用为洋葱模型:请求由外至内,响应由内至外。主要特性如下:

  • 处理函数(中间件)均以返回error的形式响应出错,方便使用统一的出错处理中间件将出错统一转换为对应的输出(JSON),并根据出错的类型等生成各类统计分析
  • 成功响应数据直接赋值至Context.Body(any),由统一的响应中间件将其转换为对应的输出(JSON,XML)
  • 支持不同种类的事件,如OnBeforeOnDoneOnError等,方便添加各类统计行为

如何使用elton开发WEB后端程序,可以参考一步一步学习如何使用elton

安装

go get github.com/vicanso/elton/v2

从 1.x 升级请参考2.0 迁移指南

Hello, World!

下面我们来演示如何使用elton返回Hello, World!,并且添加了一些常用的中间件。

package main

import (
	"github.com/vicanso/elton/v2"
	"github.com/vicanso/elton/v2/middleware"
)

func main() {
	e := elton.New()

	// Recover + Error + RequestID + BodyParser + Fresh + ETag + Responder
	e.Use(middleware.Recommended()...)
	// 可选:e.Use(middleware.NewDefaultTimeout(5*time.Second))
	// 可选:e.Use(middleware.NewDefaultCORS())

	e.GET("/", func(c *elton.Context) error {
		c.Body = &struct {
			Message string `json:"message,omitempty"`
		}{
			"Hello, World!",
		}
		return nil
	})

	e.GET("/books/{id}", func(c *elton.Context) error {
		c.Body = &struct {
			ID string `json:"id,omitempty"`
		}{
			c.Param("id"),
		}
		return nil
	})

	e.POST("/login", func(c *elton.Context) error {
		c.SetContentTypeByExt(".json")
		c.Body = c.RequestBody
		return nil
	})

	err := e.ListenAndServe(":3000")
	if err != nil {
		panic(err)
	}
}
go run ./examples/hello
# 或自建 main.go 后 go run .

之后在浏览器中打开http://localhost:3000/则能看到返回的Hello, World!。更多示例见 examples/

路由

elton每个路由可以添加多个中间件处理函数,根据路由与及HTTP请求方法指定不同的路由处理函数。而全局的中间件则可通过Use方法来添加。

e.Use(...func(*elton.Context) error)
e.Method(path string, ...func(*elton.Context) error)
  • eelton实例化对象
  • Method 为HTTP的请求方法,如:GET, PUT, POST等等
  • path 为HTTP路由路径
  • func(*elton.Context) error 为路由处理函数(中间件),当匹配的路由被请求时,对应的处理函数则会被调用
路由示例

路由使用 Go 1.22+ 标准库 net/http.ServeMux 的 pattern({name}{name...}、方法匹配)。

// 带参数路由
e.GET("/users/{type}", func(c *elton.Context) error {
	c.BodyBuffer = bytes.NewBufferString(c.Param("type"))
	return nil
})

// 捕获剩余路径
e.GET("/files/{path...}", func(c *elton.Context) error {
	c.BodyBuffer = bytes.NewBufferString(c.Param("path"))
	return nil
})

// 带中间件的路由配置
e.GET("/users/me", func(c *elton.Context) error {
	c.Set("account", "tree.xie")
	return c.Next()
}, func(c *elton.Context) error {
	c.BodyBuffer = bytes.NewBufferString(elton.GetContextValue[string](c, "account"))
	return nil
})

中间件

简单方便的中间件机制,依赖各类定制的中间件,通过各类中间件的组合,方便快捷实现各类HTTP服务,简单介绍数据响应与出错处理的中间件。需要注意,elton中默认不会执行所有的中间件,每个中间件决定是否需要执行后续处理,如果需要则调用Next()函数,与gin不一样(gin默认为执行所有,若不希望执行后续的中间件,则调用Abort)。

responder

HTTP请求响应数据时,需要将数据转换为Buffer返回,而在应用时响应数据一般为各类的struct或map等结构化数据,因此elton提供了Bodyany)字段来保存这些数据,再由中间件转换为对应的字节数据。内置的 middleware.NewDefaultResponder() 会将 struct/map 转为 JSON 并设置 Content-Type,对 string/[]byte 则直接输出。

package main

import (
	"github.com/vicanso/elton/v2"
	"github.com/vicanso/elton/v2/middleware"
)

func main() {

	e := elton.New()
	// 对响应数据 c.Body 转换为相应的json响应
	e.Use(middleware.NewDefaultResponder())

	getSession := func(c *elton.Context) error {
		c.Set("account", "tree.xie")
		return c.Next()
	}
	e.GET("/users/me", getSession, func(c *elton.Context) (err error) {
		c.Body = &struct {
			Name string `json:"name"`
			Type string `json:"type"`
		}{
			elton.GetContextValue[string](c, "account"),
			"vip",
		}
		return
	})

	err := e.ListenAndServe(":3000")
	if err != nil {
		panic(err)
	}
}
error

当请求处理失败时,直接返回error则可,elton从error中获取出错信息并输出。默认的出错处理并不适合实际应用场景,建议使用自定义出错类配合中间件,便于统一的错误处理,程序监控,下面是引入错误中间件将出错转换为json形式的响应。

package main

import (
	"github.com/vicanso/elton/v2"
	"github.com/vicanso/elton/v2/middleware"
	"github.com/vicanso/hes"
)

func main() {

	e := elton.New()
	// 指定出错以json的形式返回
	e.Use(middleware.NewError(middleware.ErrorConfig{
		ResponseType: "json",
	}))

	e.GET("/", func(c *elton.Context) (err error) {
		err = &hes.Error{
			StatusCode: 400,
			Category:   "users",
			Message:    "出错啦",
		}
		return
	})

	err := e.ListenAndServe(":3000")
	if err != nil {
		panic(err)
	}
}

更多的中间件可以参考middlewares

bench

go test -bench=. -benchmem ./...

参考结果(darwin/arm64,elton 2.0 / Go 1.24+):

goos: darwin
goarch: arm64
pkg: github.com/vicanso/elton/v2
BenchmarkRoutes-12                 	18873722	        55.69 ns/op	     120 B/op	       2 allocs/op
BenchmarkGetFunctionName-12        	295134098	         4.082 ns/op	       0 B/op	       0 allocs/op
BenchmarkContextGet-12             	57954447	        20.43 ns/op	       0 B/op	       0 allocs/op
BenchmarkContextNewMap-12          	227259025	         5.333 ns/op	       0 B/op	       0 allocs/op
BenchmarkConvertServerTiming-12    	 3219936	       367.6 ns/op	     360 B/op	      11 allocs/op
BenchmarkStatus-12                 	1000000000	         0.2438 ns/op	       0 B/op	       0 allocs/op
BenchmarkFresh-12                  	 2878122	       407.8 ns/op	     326 B/op	       8 allocs/op
BenchmarkStatic-12                 	   64177	     17887 ns/op	   21147 B/op	     471 allocs/op
BenchmarkGitHubAPI-12              	   40027	     29236 ns/op	   26832 B/op	     609 allocs/op
BenchmarkGplusAPI-12               	  837277	      1295 ns/op	    1744 B/op	      39 allocs/op
BenchmarkParseAPI-12               	  445596	      2526 ns/op	    3479 B/op	      78 allocs/op
BenchmarkRWMutexSignedKeys-12      	313402153	         3.828 ns/op	       0 B/op	       0 allocs/op
BenchmarkAtomicSignedKeys-12       	1000000000	         0.7715 ns/op	       0 B/op	       0 allocs/op
BenchmarkReadAllInitCap-12         	     520	   2258030 ns/op	73546877 B/op	      14 allocs/op
PASS
ok  	github.com/vicanso/elton/v2
goos: darwin
goarch: arm64
pkg: github.com/vicanso/elton/v2/middleware
BenchmarkBodyParserBufferPool-12    	  219397	      5430 ns/op	   23393 B/op	      24 allocs/op
BenchmarkGenETag-12                 	  878080	      1370 ns/op	     128 B/op	       5 allocs/op
BenchmarkMd5-12                     	  251551	      4744 ns/op	      96 B/op	       5 allocs/op
BenchmarkNewShortHTTPHeader-12      	23356375	        51.05 ns/op	      80 B/op	       2 allocs/op
BenchmarkNewHTTPHeader-12           	17233610	        69.85 ns/op	      88 B/op	       3 allocs/op
BenchmarkNewHTTPHeaders-12          	 1528754	       797.2 ns/op	    1136 B/op	      23 allocs/op
BenchmarkHTTPHeaderMarshal-12       	 1501634	       797.6 ns/op	     920 B/op	      16 allocs/op
BenchmarkToHTTPHeader-12            	 1452776	       842.2 ns/op	    1272 B/op	      34 allocs/op
BenchmarkHTTPHeaderUnmarshal-12     	  513957	      2328 ns/op	    1216 B/op	      36 allocs/op
BenchmarkLRUStore-12                	13680637	        87.71 ns/op	      16 B/op	       1 allocs/op
BenchmarkProxy-12                   	   25860	     45085 ns/op	   20476 B/op	     112 allocs/op
PASS
ok  	github.com/vicanso/elton/v2/middleware

Documentation

Index

Constants

View Source
const (
	// ErrCategory elton category
	ErrCategory = "elton"
	// HeaderXForwardedFor x-forwarded-for
	HeaderXForwardedFor = "X-Forwarded-For"
	// HeaderXRealIP x-real-ip
	HeaderXRealIP = "X-Real-Ip"
	// HeaderSetCookie Set-Cookie
	HeaderSetCookie = "Set-Cookie"
	// HeaderLocation Location
	HeaderLocation = "Location"
	// HeaderContentType Content-Type
	HeaderContentType = "Content-Type"
	// HeaderAuthorization Authorization
	HeaderAuthorization = "Authorization"
	// HeaderWWWAuthenticate WWW-Authenticate
	HeaderWWWAuthenticate = "WWW-Authenticate"
	// HeaderCacheControl Cache-Control
	HeaderCacheControl = "Cache-Control"
	// HeaderETag ETag
	HeaderETag = "ETag"
	// HeaderLastModified last modified
	HeaderLastModified = "Last-Modified"
	// HeaderContentEncoding content encoding
	HeaderContentEncoding = "Content-Encoding"
	// HeaderContentLength content length
	HeaderContentLength = "Content-Length"
	// HeaderIfModifiedSince if modified since
	HeaderIfModifiedSince = "If-Modified-Since"
	// HeaderIfNoneMatch if none match
	HeaderIfNoneMatch = "If-None-Match"
	// HeaderAcceptEncoding accept encoding
	HeaderAcceptEncoding = "Accept-Encoding"
	// HeaderServerTiming server timing
	HeaderServerTiming = "Server-Timing"
	// HeaderTransferEncoding transfer encoding
	HeaderTransferEncoding = "Transfer-Encoding"

	// MinRedirectCode min redirect code
	MinRedirectCode = 300
	// MaxRedirectCode max redirect code
	MaxRedirectCode = 308

	// MIMETextPlain text plain
	MIMETextPlain = "text/plain; charset=utf-8"
	// MIMEApplicationJSON application json
	MIMEApplicationJSON = "application/json; charset=utf-8"
	// MIMEBinary binary data
	MIMEBinary = "application/octet-stream"

	// Gzip gzip compress
	Gzip = "gzip"
	// Br brotli compress
	Br = "br"
	// Zstd zstd compress
	Zstd = "zstd"
)
View Source
const (
	// SignedCookieSuffix signed cookie suffix
	SignedCookieSuffix = ".sig"
)

Variables

View Source
var (

	// ErrInvalidRedirect invalid redirect
	ErrInvalidRedirect = &hes.Error{
		StatusCode: 400,
		Message:    "invalid redirect",
		Category:   ErrCategory,
	}

	// ErrFileNotFound file not found
	ErrFileNotFound = &hes.Error{
		StatusCode: 404,
		Message:    "file not found",
		Category:   ErrCategory,
	}
)
View Source
var (
	// ServerTimingDur server timing dur
	ServerTimingDur = []byte(";dur=")
	// ServerTimingDesc server timing desc
	ServerTimingDesc = []byte(`;desc="`)
	// ServerTimingEnd server timing end
	ServerTimingEnd = []byte(`"`)
)
View Source
var DefaultTemplateParsers = NewTemplateParsers()
View Source
var ErrServerNotInitialized = errors.New("server is not initialized")

ErrServerNotInitialized the http server of elton is not initialized

View Source
var (
	ErrSignKeyIsNil = hes.New("keys for sign cookie can't be nil")
)

Functions

func DefaultSkipper

func DefaultSkipper(c *Context) bool

DefaultSkipper default skipper function

func Fresh

func Fresh(reqHeader http.Header, resHeader http.Header) bool

Fresh returns fresh status by judging request header and response header

func GetClientIP

func GetClientIP(req *http.Request) string

GetClientIP returns the client ip of request, it will get ip from x-forwarded-for from request header and get the first public ip, if not exists then it will get ip from x-real-ip from request header, if not exists then it will use remote addr.

func GetContextValue

func GetContextValue[T any](c *Context, key any) T

GetContextValue returns the value of the key from the context store. The zero value of T will be returned if the key does not exist or the value doesn't match type T.

func GetRealIP

func GetRealIP(req *http.Request) string

GetRealIP returns the real ip of request, it will get ip from x-forwarded-for from request header, if not exists then it will get ip from x-real-ip from request header, if not exists then it will use remote addr.

func GetRemoteAddr

func GetRemoteAddr(req *http.Request) string

GetRemoteAddr returns the remote addr of request

func IsIntranet

func IsIntranet(s string) bool

IsIntranet reports whether s is a loopback, private, or link-local address. Invalid or empty values return false.

func ReadAllInitCap

func ReadAllInitCap(r io.Reader, initCap int) ([]byte, error)

copy from io.ReadAll ReadAll reads from r until an error or EOF and returns the data it read. A successful call returns err == nil, not err == EOF. Because ReadAll is defined to read from src until EOF, it does not treat an EOF from Read as an error to be reported.

func ReadAllToBuffer

func ReadAllToBuffer(r io.Reader, buffer *bytes.Buffer) error

ReadAllToBuffer reads from r until an error or EOF and writes data to buffer. A successful call returns err == nil, not err == EOF.

Types

type AtomicSignedKeys

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

AtomicSignedKeys atomic toggle signed keys

func (*AtomicSignedKeys) Keys

func (atSk *AtomicSignedKeys) Keys() []string

Keys returns the key list of atomic signed keys

func (*AtomicSignedKeys) SetKeys

func (atSk *AtomicSignedKeys) SetKeys(values []string)

SetKeys sets the key list of atomic signed keys

type BeforeListener

type BeforeListener func(*Context)

BeforeListener before request handle listener

type BufferPool

type BufferPool interface {
	Get() *bytes.Buffer
	Put(*bytes.Buffer)
}

A BufferPool is an interface for getting and returning temporary buffer

func NewBufferPool

func NewBufferPool(initCap int) BufferPool

NewBufferPool creates a buffer pool, if the init cap gt 0, the buffer will be init with cap size

type Context

type Context struct {
	Request  *http.Request
	Response http.ResponseWriter
	// Committed commit the data to response, when it's true, the response has been sent.
	// If using custom response handler, please set it true.
	Committed bool
	// ID context id, using unique string function to generate it.
	ID string
	// Route route path, it's equal to the http router path with params.
	Route string
	// Next advances the middleware/handler chain. Set by the framework (stable boundNext);
	// Compose may temporarily replace it. Prefer calling Next() rather than reassigning.
	Next func() error
	// Params route params
	Params *RouteParams
	// StatusCode http response's status code, default is 0 which will be handle as 200
	StatusCode int
	// Body http response's body, which should be converted to bytes by responder middleware.
	// JSON response middleware,  xml response middleware and so on.
	// 约定:io.Reader类型的Body由框架流式写出(实现io.Closer会被自动关闭);
	// 其它类型需由responder等中间件转换为BodyBuffer后输出
	Body any
	// BodyBuffer http response's body buffer, it should be set by responder middleware.
	BodyBuffer *bytes.Buffer
	// RequestBody http request body, which should be converted by request body parser middleware.
	RequestBody []byte
	// contains filtered or unexported fields
}

Context elton context

func NewContext

func NewContext(resp http.ResponseWriter, req *http.Request) *Context

NewContext return a new context

func (*Context) AddCookie

func (c *Context) AddCookie(cookie *http.Cookie)

AddCookie adds the cookie to the response

func (*Context) AddHeader

func (c *Context) AddHeader(key, value string)

AddHeader adds the key/value to response header. It appends to any existing value of the key.

func (*Context) AddRequestHeader

func (c *Context) AddRequestHeader(key, value string)

AddRequestHeader adds the key/value to http header. It appends to any existing value of the key.

func (*Context) AddSignedCookie

func (c *Context) AddSignedCookie(cookie *http.Cookie)

AddSignedCookie adds cookie to the response, it will also add a signed cookie

func (*Context) CacheMaxAge

func (c *Context) CacheMaxAge(age time.Duration, sMaxAge ...time.Duration)

CacheMaxAge sets `Cache-Control: public, max-age=MaxAge, s-maxage=SMaxAge` to the http response header. If sMaxAge is not empty, it will use the first duration as SMaxAge

func (*Context) ClientIP

func (c *Context) ClientIP() string

ClientIP returns the client ip of request, it will get ip from x-forwared-for from request header and get the first public ip, if not exists then it will get ip from x-real-ip from request header, if not exists then it will use remote addr.

func (*Context) Context

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

Context returns context of request

func (*Context) Cookie

func (c *Context) Cookie(name string) (*http.Cookie, error)

Cookie return the cookie from http request

func (*Context) Created

func (c *Context) Created(body any)

Created sets the body to response and set the status to 201

func (*Context) Deadline

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

func (*Context) DisableReuse

func (c *Context) DisableReuse()

DisableReuse sets the context disable reuse

func (*Context) Done

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

func (*Context) Elton

func (c *Context) Elton() *Elton

Elton returns the elton instance of context

func (*Context) Err

func (c *Context) Err() error

func (*Context) Get

func (c *Context) Get(key any) (any, bool)

Get the value from context

func (*Context) GetHeader

func (c *Context) GetHeader(key string) string

GetHeader returns header value from http response. Note: unqualified header methods (GetHeader/SetHeader/AddHeader) operate on the RESPONSE header, use GetRequestHeader to read the request header

func (*Context) GetRequestHeader

func (c *Context) GetRequestHeader(key string) string

GetRequestHeader returns header value from http request

func (*Context) HTML

func (c *Context) HTML(html string)

HTML sets content type and response body as html

func (*Context) Header

func (c *Context) Header() http.Header

Header returns headers of http response

func (*Context) IsReaderBody

func (c *Context) IsReaderBody() bool

IsReaderBody judgets whether body is reader

func (*Context) MergeHeader

func (c *Context) MergeHeader(h http.Header)

MergeHeader merges http header to response header

func (*Context) NewTrace

func (c *Context) NewTrace() *Trace

NewTrace returns a new trace and set it to context value

func (*Context) NoCache

func (c *Context) NoCache()

NoCache sets `Cache-Control: no-cache` to the http response header

func (*Context) NoContent

func (c *Context) NoContent()

NoContent clean all content and set status to 204

func (*Context) NoStore

func (c *Context) NoStore()

NoStore sets `Cache-Control: no-store` to the http response header

func (*Context) NotModified

func (c *Context) NotModified()

NotModified clean all content and set status to 304

func (*Context) Param

func (c *Context) Param(name string) string

Param returns the route param value. Prefer Request.PathValue (ServeMux); fall back to Params for manual/test setups.

func (*Context) Pass

func (c *Context) Pass(another *Elton)

Pass request to another elton instance and set the context is committed

func (*Context) Pipe

func (c *Context) Pipe(r io.Reader) (int64, error)

Pipe the reader to the response

func (*Context) PrivateCacheMaxAge

func (c *Context) PrivateCacheMaxAge(age time.Duration)

PrivateCacheMaxAge sets `Cache-Control: private, max-age=MaxAge` to the response header.

func (*Context) Query

func (c *Context) Query() map[string]string

Query returns the query map. It will return map[string]string, not the same as url.Values If want to get url.Values, use c.Request.URL.Query()

func (*Context) QueryParam

func (c *Context) QueryParam(name string) string

QueryParam returns the query param value

func (*Context) ReadFormFile

func (c *Context) ReadFormFile(key string) ([]byte, *multipart.FileHeader, error)

ReadFormFile reads the multipart form file data from request

func (*Context) RealIP

func (c *Context) RealIP() string

RealIP returns the real ip of request, it will get ip from x-forwarded-for from request header, if not exists then it will get ip from x-real-ip from request header, if not exists then it will use remote addr.

func (*Context) Redirect

func (c *Context) Redirect(code int, url string) error

Redirect the http request to new location

func (*Context) RemoteAddr

func (c *Context) RemoteAddr() string

RemoteAddr returns the remote addr of request

func (*Context) Reset

func (c *Context) Reset()

Reset all fields of context

func (*Context) ResetHeader

func (c *Context) ResetHeader()

ResetHeader resets response header

func (*Context) SendFile

func (c *Context) SendFile(file string) error

SendFile to http response

func (*Context) ServerTiming

func (c *Context) ServerTiming(traceInfos TraceInfos, prefix string)

ServerTiming converts trace info to http response server timing

func (*Context) Set

func (c *Context) Set(key, value any)

Set the value to the context

func (*Context) SetContentTypeByExt

func (c *Context) SetContentTypeByExt(file string)

SetContentTypeByExt sets content type by file extname

func (*Context) SetHeader

func (c *Context) SetHeader(key, value string)

SetHeader sets the key/value to response header. It replaces any existing values of the key.

func (*Context) SetRequestHeader

func (c *Context) SetRequestHeader(key, value string)

SetRequestHeader sets http header to request. It replaces any existing values of the key.

func (*Context) SignedCookie

func (c *Context) SignedCookie(name string) (*http.Cookie, error)

SignedCookie returns signed cookie from http request

func (*Context) SignedCookieWithIndex

func (c *Context) SignedCookieWithIndex(name string) (*http.Cookie, int, error)

SignedCookieWithIndex returns signed cookie from http request

func (*Context) Trace

func (c *Context) Trace() *Trace

Trace gets trace from context, if context without trace, new trace will be created.

func (*Context) Value

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

func (*Context) WithContext

func (c *Context) WithContext(ctx context.Context) *Context

WithContext changes the request to new request with context

func (*Context) Write

func (c *Context) Write(buf []byte) (int, error)

Write the response body

func (*Context) WriteHeader

func (c *Context) WriteHeader(statusCode int)

WriteHeader sets the http status code

type ContextKey

type ContextKey string
const ContextTraceKey ContextKey = "contextTrace"

type DoneListener

type DoneListener func(*Context)

DoneListener request done listener

type Elton

type Elton struct {
	// Server http server
	Server *http.Server
	// ErrorHandler set the function for error handler
	ErrorHandler ErrorHandler
	// NotFoundHandler set the function for not found handler
	NotFoundHandler http.HandlerFunc
	// MethodNotAllowedHandler set the function for method not allowed handler
	MethodNotAllowedHandler http.HandlerFunc
	// GenerateID generate id function, will use it to create context's id
	GenerateID GenerateID
	// EnableTrace enable trace
	EnableTrace bool
	// SignedKeys signed keys
	SignedKeys SignedKeysGenerator
	// contains filtered or unexported fields
}

Elton web framework instance

func New

func New() *Elton

New returns a new elton instance

func NewWithoutServer

func NewWithoutServer() *Elton

NewWithoutServer returns a new elton instance without http server

func (*Elton) ALL

func (e *Elton) ALL(path string, handlerList ...Handler) *Elton

ALL adds http all method handle

func (*Elton) AddGroup

func (e *Elton) AddGroup(groups ...*Group) *Elton

AddGroup adds the group and its sub groups to elton

func (*Elton) Close

func (e *Elton) Close() error

Close closes the http server

func (*Elton) Closing

func (e *Elton) Closing() bool

Closing judge the status whether is closing

func (*Elton) DELETE

func (e *Elton) DELETE(path string, handlerList ...Handler) *Elton

DELETE adds http delete method handle

func (*Elton) EmitError

func (e *Elton) EmitError(c *Context, err error) *Elton

EmitError emits an error event, it will call the listen functions of error event

func (*Elton) EmitTrace

func (e *Elton) EmitTrace(c *Context, infos TraceInfos) *Elton

EmitTrace emits a trace event, it will call the listen functions of trace event

func (*Elton) GET

func (e *Elton) GET(path string, handlerList ...Handler) *Elton

GET adds http get method handle

func (*Elton) GetFunctionName

func (e *Elton) GetFunctionName(fn any) string

GetFunctionName return the name of handler function

func (*Elton) GracefulClose

func (e *Elton) GracefulClose(ctx context.Context, delay time.Duration) error

GracefulClose closes the http server gracefully. It sets the status to be closing (rejecting new requests with 503), waits for the delay, then shuts down the server. ctx取消时停止等待并立即进入shutdown(此时Shutdown会关闭监听 并立即返回ctx.Err,不再等待活跃连接处理完成)。

func (*Elton) HEAD

func (e *Elton) HEAD(path string, handlerList ...Handler) *Elton

HEAD adds http head method handle

func (*Elton) Handle

func (e *Elton) Handle(method, path string, handlerList ...Handler) *Elton

Handle adds http handle function. 注册时将当时的全局中间件(Use)与该路由 handler 快照合并为一条固定执行链; 请求到达时通过 c.Next() 推进(洋葱模型),Next 使用 Context 上复用的 boundNext, 避免每请求分配闭包:

  • 任一环节返回 error 则中断,触发 error 监听器并输出错误响应;
  • c.Committed 为 true 时 Next 短路,不再执行后续 handler;
  • 链执行完成后,统一将 BodyBuffer(或 reader 类型的 Body)写出至响应。

path 使用 net/http ServeMux 模式(Go 1.22+):{name}、{name...}、{$}; 仍兼容段首 :name 与末尾 /*(分别转为 {name}、{path...})。 注册 pattern 为 "METHOD path";冲突的 pattern 会 panic(标准库行为)。

注意:应在 Listen 前完成 Use + 路由注册。某路由注册之后再 Use 的中间件 不会作用于该路由(链在 Handle 时已快照)。

func (*Elton) ListenAndServe

func (e *Elton) ListenAndServe(addr string) error

ListenAndServe listens the addr and serve http, it returns ErrServerNotInitialized if the server of elton is nil.

func (*Elton) ListenAndServeTLS

func (e *Elton) ListenAndServeTLS(addr, certFile, keyFile string) error

ListenAndServeTLS listens the addr and serve https, it returns ErrServerNotInitialized if the server of elton is nil.

func (*Elton) Multi

func (e *Elton) Multi(methods []string, path string, handlerList ...Handler) *Elton

Multi adds multi method

func (*Elton) OPTIONS

func (e *Elton) OPTIONS(path string, handlerList ...Handler) *Elton

OPTIONS adds http options method handle

func (*Elton) OnBefore

func (e *Elton) OnBefore(ln BeforeListener) *Elton

OnBefore adds listen to before request done(after pre middlewares, before middlewares)

func (*Elton) OnDone

func (e *Elton) OnDone(ln DoneListener) *Elton

OnDone adds listen to request done, it will be triggered when the request handle is done

func (*Elton) OnError

func (e *Elton) OnError(ln ErrorListener) *Elton

OnError adds listen to error event

func (*Elton) OnTrace

func (e *Elton) OnTrace(ln TraceListener) *Elton

OnTrace adds listen to trace event

func (*Elton) PATCH

func (e *Elton) PATCH(path string, handlerList ...Handler) *Elton

PATCH adds http patch method handle

func (*Elton) POST

func (e *Elton) POST(path string, handlerList ...Handler) *Elton

POST adds http post method handle

func (*Elton) PUT

func (e *Elton) PUT(path string, handlerList ...Handler) *Elton

PUT adds http put method handle

func (*Elton) Pre

func (e *Elton) Pre(handlerList ...PreHandler) *Elton

Pre adds pre middleware function handler to elton's pre middleware list

func (*Elton) Routers

func (e *Elton) Routers() []RouterInfo

Routers returns routers of elton

func (*Elton) Running

func (e *Elton) Running() bool

Running judge the status whether is running

func (*Elton) Serve

func (e *Elton) Serve(l net.Listener) error

Serve serves http server, it returns ErrServerNotInitialized if the server of elton is nil.

func (*Elton) ServeHTTP

func (e *Elton) ServeHTTP(resp http.ResponseWriter, req *http.Request)

ServeHTTP http handler

func (*Elton) SetFunctionName

func (e *Elton) SetFunctionName(fn any, name string)

SetFunctionName sets the name of handler function, it will use to http timing

func (*Elton) Shutdown

func (e *Elton) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the http server without interrupting any active connections

func (*Elton) Status

func (e *Elton) Status() Status

Status returns status of elton

func (*Elton) TRACE

func (e *Elton) TRACE(path string, handlerList ...Handler) *Elton

TRACE adds http trace method handle

func (*Elton) Use

func (e *Elton) Use(handlerList ...Handler) *Elton

Use adds middleware handler function to elton's middleware list

func (*Elton) UseWithName

func (e *Elton) UseWithName(handler Handler, name string) *Elton

UseWithName adds middleware and set handler function's name

type ErrorHandler

type ErrorHandler func(*Context, error)

ErrorHandler error handle function

type ErrorListener

type ErrorListener func(*Context, error)

ErrorListener error listener function

type GenerateID

type GenerateID func() string

GenerateID generate context id

type Group

type Group struct {
	Path        string
	HandlerList []Handler
	// contains filtered or unexported fields
}

Group group router

func NewGroup

func NewGroup(path string, handlerList ...Handler) *Group

NewGroup returns a new router group

func (*Group) ALL

func (g *Group) ALL(path string, handlerList ...Handler) *Group

ALL adds http all methods handler to group

func (*Group) DELETE

func (g *Group) DELETE(path string, handlerList ...Handler) *Group

DELETE adds http delete method handler to group

func (*Group) GET

func (g *Group) GET(path string, handlerList ...Handler) *Group

GET adds http get method handler to group

func (*Group) HEAD

func (g *Group) HEAD(path string, handlerList ...Handler) *Group

HEAD adds http head method handler to group

func (*Group) Multi

func (g *Group) Multi(methods []string, path string, handlerList ...Handler) *Group

Multi adds multi http methods handler to group

func (*Group) NewGroup

func (g *Group) NewGroup(path string, handlerList ...Handler) *Group

NewGroup returns a new sub group of the group, the path and handler list will be merged with the parent's. The sub group will be added to elton together with its parent by elton.AddGroup.

func (*Group) OPTIONS

func (g *Group) OPTIONS(path string, handlerList ...Handler) *Group

OPTIONS adds http options method handler to group

func (*Group) PATCH

func (g *Group) PATCH(path string, handlerList ...Handler) *Group

PATCH adds http patch method handler to group

func (*Group) POST

func (g *Group) POST(path string, handlerList ...Handler) *Group

POST adds http post method handler to group

func (*Group) PUT

func (g *Group) PUT(path string, handlerList ...Handler) *Group

PUT adds http put method handler to group

func (*Group) TRACE

func (g *Group) TRACE(path string, handlerList ...Handler) *Group

TRACE adds http trace method handler to group

type HTMLTemplate

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

func NewHTMLTemplate

func NewHTMLTemplate(read ReadFile) *HTMLTemplate

func (*HTMLTemplate) Render

func (ht *HTMLTemplate) Render(ctx context.Context, text string, data any) (string, error)

Render renders the text using text/template

func (*HTMLTemplate) RenderFile

func (ht *HTMLTemplate) RenderFile(ctx context.Context, filename string, data any) (string, error)

Render renders the text of file using text/template

type Handler

type Handler func(*Context) error

Handler elton handle function

func Compose

func Compose(handlerList ...Handler) Handler

Compose composes handler list as a handler

type MultipartForm

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

func NewMultipartForm

func NewMultipartForm() *MultipartForm

NewMultipartForm returns a new multipart form, the form data will be saved as tmp file for less memory.

func (*MultipartForm) AddField

func (f *MultipartForm) AddField(name, value string) error

AddField adds a field to form

func (*MultipartForm) AddFile

func (f *MultipartForm) AddFile(name, filename string, reader ...io.Reader) error

AddFile add a file to form, if the reader is nil, the filename will be used to open as reader

func (*MultipartForm) Close

func (f *MultipartForm) Close() error

Close closes the writer and removes the tmpfile

func (*MultipartForm) ContentType

func (f *MultipartForm) ContentType() string

ContentType returns the content type of form

func (*MultipartForm) Reader

func (f *MultipartForm) Reader() (io.Reader, error)

Reader returns a render of form

type PreHandler

type PreHandler func(*http.Request)

PreHandler pre handler

type RWMutexSignedKeys

type RWMutexSignedKeys struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

RWMutexSignedKeys read/write mutex signed key

func (*RWMutexSignedKeys) Keys

func (rwSk *RWMutexSignedKeys) Keys() []string

Keys returns the key list of rwmutex signed keys

func (*RWMutexSignedKeys) SetKeys

func (rwSk *RWMutexSignedKeys) SetKeys(values []string)

SetKeys sets the key list of rwmutex signed keys

type ReadFile

type ReadFile func(filename string) ([]byte, error)

ReadFile defines how to read file

type RouteParams

type RouteParams struct {
	Keys, Values []string
}

RouteParams tracks URL path wildcards for a request. Values are filled from http.Request.PathValue after ServeMux matches a route.

func (*RouteParams) Add

func (s *RouteParams) Add(key, value string)

Add appends a path parameter.

func (*RouteParams) Get

func (s *RouteParams) Get(key string) string

Get returns the value for key, or "" if missing.

func (*RouteParams) Reset

func (s *RouteParams) Reset()

Reset clears all parameters for pool reuse.

func (*RouteParams) ToMap

func (s *RouteParams) ToMap() map[string]string

ToMap converts route params to map[string]string.

type Router

type Router struct {
	Method     string    `json:"method,omitempty"`
	Path       string    `json:"path,omitempty"`
	HandleList []Handler `json:"-"`
}

Router router

type RouterInfo

type RouterInfo struct {
	Method string `json:"method,omitempty"`
	Route  string `json:"route,omitempty"`
}

RouterInfo router's info

type SignedKeysGenerator

type SignedKeysGenerator interface {
	Keys() []string
	SetKeys([]string)
}

SignedKeysGenerator signed keys generator

type SimpleSignedKeys

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

SimpleSignedKeys simple sigined key

func (*SimpleSignedKeys) Keys

func (sk *SimpleSignedKeys) Keys() []string

Keys returns the key list of simple signed keys

func (*SimpleSignedKeys) SetKeys

func (sk *SimpleSignedKeys) SetKeys(values []string)

SetKeys sets the key list of simple signed keys

type Skipper

type Skipper func(c *Context) bool

Skipper check for skip middleware

type Status

type Status int32

Status is the running status of elton

const (
	// StatusRunning running status
	StatusRunning Status = iota
	// StatusClosing closing status
	StatusClosing
	// StatusClosed closed status
	StatusClosed
)

type TemplateParser

type TemplateParser interface {
	Render(ctx context.Context, text string, data any) (string, error)
	RenderFile(ctx context.Context, filename string, data any) (string, error)
}

type TemplateParsers

type TemplateParsers map[string]TemplateParser

func NewTemplateParsers

func NewTemplateParsers() TemplateParsers

func (TemplateParsers) Add

func (tps TemplateParsers) Add(template string, parser TemplateParser)

func (TemplateParsers) Get

func (tps TemplateParsers) Get(template string) TemplateParser

type Trace

type Trace struct {
	Infos TraceInfos
	// contains filtered or unexported fields
}

func NewTrace

func NewTrace() *Trace

NewTrace returns a new trace

func TraceFromContext

func TraceFromContext(ctx context.Context) *Trace

TraceFromContext gets trace from context, if context without trace, new trace will be created.

func (*Trace) Add

func (t *Trace) Add(info *TraceInfo) *Trace

Add adds trace info to trace

func (*Trace) Calculate

func (t *Trace) Calculate()

Calculate calculates the duration of middleware. 中间件采用洋葱模型,前面中间件记录的时长包含了它调用Next()之后 所有后续中间件的时长。由于trace信息按执行顺序添加, 依次让每个中间件减去紧随其后的中间件时长,即得到各自的真实耗时。

func (*Trace) Start

func (t *Trace) Start(name string) func()

Start starts a sub trace and return done function for sub trace.

type TraceInfo

type TraceInfo struct {
	Middleware bool          `json:"-"`
	Name       string        `json:"name,omitempty"`
	Duration   time.Duration `json:"duration,omitempty"`
}

TraceInfo trace's info

type TraceInfos

type TraceInfos []*TraceInfo

TraceInfos trace infos

func (TraceInfos) Filter

func (traceInfos TraceInfos) Filter(fn func(*TraceInfo) bool) TraceInfos

Filter filters the trace info, the new trace infos will be returned.

func (TraceInfos) FilterDurationGreaterThan

func (traceInfos TraceInfos) FilterDurationGreaterThan(d time.Duration) TraceInfos

FilterDurationGreaterThan filters the trace infos of which duration is greater than d.

func (TraceInfos) ServerTiming

func (traceInfos TraceInfos) ServerTiming(prefix string) string

ServerTiming return server timing with prefix

type TraceListener

type TraceListener func(*Context, TraceInfos)

TraceListener trace listener

Directories

Path Synopsis
examples
api command
API example: Recommended + CORS + Timeout + nested groups.
API example: Recommended + CORS + Timeout + nested groups.
hello command
Hello example: Recommended middleware stack + simple JSON routes.
Hello example: Recommended middleware stack + simple JSON routes.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

Jump to

Keyboard shortcuts

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