wo

package module
v0.0.0-...-1ef12ea Latest Latest
Warning

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

Go to latest
Published: Jan 13, 2026 License: MIT Imports: 28 Imported by: 0

README

Wo - Modern HTTP Web Framework for Go

Go Reference Go Report Card codecov License

Wo is a modern, high-performance HTTP web framework built with Go 1.25+ generics. It features a type-safe routing system with comprehensive middleware support, event-driven request processing, and a clean, expressive API.

Installation
go get github.com/gowool/wo

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Portions of this codebase are inspired by and copied from PocketBase under the MIT License.

Documentation

Index

Constants

View Source
const (
	CharsetUTF8         = "charset=UTF-8"
	XMLHTTPRequest      = "XMLHttpRequest"
	IndexPage           = "index.html"
	StaticWildcardParam = "path"
	DefaultMaxMemory    = 32 << 20 // 32mb

)
View Source
const (
	// MIMEApplicationJSON JavaScript Object Notation (JSON) https://www.rfc-editor.org/rfc/rfc8259
	MIMEApplicationJSON                  = "application/json"
	MIMEApplicationJavaScript            = "application/javascript"
	MIMEApplicationJavaScriptCharsetUTF8 = MIMEApplicationJavaScript + "; " + CharsetUTF8
	MIMEApplicationXML                   = "application/xml"
	MIMEApplicationXMLCharsetUTF8        = MIMEApplicationXML + "; " + CharsetUTF8
	MIMETextXML                          = "text/xml"
	MIMETextXMLCharsetUTF8               = MIMETextXML + "; " + CharsetUTF8
	MIMEApplicationForm                  = "application/x-www-form-urlencoded"
	MIMEApplicationProtobuf              = "application/protobuf"
	MIMEApplicationMsgpack               = "application/msgpack"
	MIMETextHTML                         = "text/html"
	MIMETextHTMLCharsetUTF8              = MIMETextHTML + "; " + CharsetUTF8
	MIMETextPlain                        = "text/plain"
	MIMETextPlainCharsetUTF8             = MIMETextPlain + "; " + CharsetUTF8
	MIMEMultipartForm                    = "multipart/form-data"
	MIMEOctetStream                      = "application/octet-stream"
	MIMEEventStream                      = "text/event-stream"
	MIMEApplicationZip                   = "application/zip"
)

MIME types

View Source
const (
	HeaderAccept         = "Accept"
	HeaderAcceptEncoding = "Accept-Encoding"
	HeaderAcceptLanguage = "Accept-Language"
	// HeaderAllow is the name of the "Allow" header field used to list the set of methods
	// advertised as supported by the target resource. Returning an Allow header is mandatory
	// for Status 405 (method not found) and useful for the OPTIONS method in responses.
	// See RFC 7231: https://datatracker.ietf.org/doc/html/rfc7231#section-7.4.1
	HeaderAllow               = "Allow"
	HeaderAuthorization       = "Authorization"
	HeaderContentDisposition  = "Content-Disposition"
	HeaderContentEncoding     = "Content-Encoding"
	HeaderContentLength       = "Content-Length"
	HeaderContentType         = "Content-Type"
	HeaderCookie              = "Cookie"
	HeaderSetCookie           = "Set-Cookie"
	HeaderIfModifiedSince     = "If-Modified-Since"
	HeaderLastModified        = "Last-Modified"
	HeaderLocation            = "Location"
	HeaderRetryAfter          = "Retry-After"
	HeaderUpgrade             = "Upgrade"
	HeaderVary                = "Vary"
	HeaderWWWAuthenticate     = "WWW-Authenticate"
	HeaderXForwardedFor       = "X-Forwarded-For"
	HeaderXForwardedProto     = "X-Forwarded-Proto"
	HeaderXForwardedProtocol  = "X-Forwarded-Protocol"
	HeaderXForwardedSsl       = "X-Forwarded-Ssl"
	HeaderXUrlScheme          = "X-Url-Scheme"
	HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
	HeaderXRealIP             = "X-Real-Ip"
	HeaderXRequestID          = "X-Request-Id"
	HeaderXCorrelationID      = "X-Correlation-Id"
	HeaderXRequestedWith      = "X-Requested-With"
	HeaderServer              = "Server"
	HeaderOrigin              = "Origin"
	HeaderCacheControl        = "Cache-Control"
	HeaderConnection          = "Connection"
	HeaderXRobotsTag          = "X-Robots-Tag"
	HeaderXRateLimitLimit     = "X-RateLimit-Limit"
	HeaderXRateLimitRemaining = "X-RateLimit-Remaining"
	HeaderXRateLimitReset     = "X-RateLimit-Reset"

	// Access control
	HeaderAccessControlRequestMethod    = "Access-Control-Request-Method"
	HeaderAccessControlRequestHeaders   = "Access-Control-Request-Headers"
	HeaderAccessControlAllowOrigin      = "Access-Control-Allow-Origin"
	HeaderAccessControlAllowMethods     = "Access-Control-Allow-Methods"
	HeaderAccessControlAllowHeaders     = "Access-Control-Allow-Headers"
	HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
	HeaderAccessControlExposeHeaders    = "Access-Control-Expose-Headers"
	HeaderAccessControlMaxAge           = "Access-Control-Max-Age"

	// Security
	HeaderStrictTransportSecurity         = "Strict-Transport-Security"
	HeaderXContentTypeOptions             = "X-Content-Type-Options"
	HeaderXXSSProtection                  = "X-XSS-Protection"
	HeaderXFrameOptions                   = "X-Frame-Options"
	HeaderContentSecurityPolicy           = "Content-Security-Policy"
	HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
	HeaderXCSRFToken                      = "X-CSRF-Token"
	HeaderReferrerPolicy                  = "Referrer-Policy"

	// Cloudflare
	// https://developers.cloudflare.com/fundamentals/reference/http-headers/#cf-ipcountry
	HeaderCFIPCountry = "CF-IPCountry"
)

Headers

Variables

View Source
var (
	ErrBadRequest                    = NewHTTPError(http.StatusBadRequest)                    // HTTP 400 Bad Request
	ErrUnauthorized                  = NewHTTPError(http.StatusUnauthorized)                  // HTTP 401 Unauthorized
	ErrPaymentRequired               = NewHTTPError(http.StatusPaymentRequired)               // HTTP 402 Payment Required
	ErrForbidden                     = NewHTTPError(http.StatusForbidden)                     // HTTP 403 Forbidden
	ErrNotFound                      = NewHTTPError(http.StatusNotFound)                      // HTTP 404 Not Found
	ErrMethodNotAllowed              = NewHTTPError(http.StatusMethodNotAllowed)              // HTTP 405 Method Not Allowed
	ErrNotAcceptable                 = NewHTTPError(http.StatusNotAcceptable)                 // HTTP 406 Not Acceptable
	ErrProxyAuthRequired             = NewHTTPError(http.StatusProxyAuthRequired)             // HTTP 407 Proxy AuthRequired
	ErrRequestTimeout                = NewHTTPError(http.StatusRequestTimeout)                // HTTP 408 Request Timeout
	ErrConflict                      = NewHTTPError(http.StatusConflict)                      // HTTP 409 Conflict
	ErrGone                          = NewHTTPError(http.StatusGone)                          // HTTP 410 Gone
	ErrLengthRequired                = NewHTTPError(http.StatusLengthRequired)                // HTTP 411 Length Required
	ErrPreconditionFailed            = NewHTTPError(http.StatusPreconditionFailed)            // HTTP 412 Precondition Failed
	ErrStatusRequestEntityTooLarge   = NewHTTPError(http.StatusRequestEntityTooLarge)         // HTTP 413 Payload Too Large
	ErrRequestURITooLong             = NewHTTPError(http.StatusRequestURITooLong)             // HTTP 414 URI Too Long
	ErrUnsupportedMediaType          = NewHTTPError(http.StatusUnsupportedMediaType)          // HTTP 415 Unsupported Media Type
	ErrRequestedRangeNotSatisfiable  = NewHTTPError(http.StatusRequestedRangeNotSatisfiable)  // HTTP 416 Range Not Satisfiable
	ErrExpectationFailed             = NewHTTPError(http.StatusExpectationFailed)             // HTTP 417 Expectation Failed
	ErrTeapot                        = NewHTTPError(http.StatusTeapot)                        // HTTP 418 I'm a teapot
	ErrMisdirectedRequest            = NewHTTPError(http.StatusMisdirectedRequest)            // HTTP 421 Misdirected Request
	ErrUnprocessableEntity           = NewHTTPError(http.StatusUnprocessableEntity)           // HTTP 422 Unprocessable Entity
	ErrLocked                        = NewHTTPError(http.StatusLocked)                        // HTTP 423 Locked
	ErrFailedDependency              = NewHTTPError(http.StatusFailedDependency)              // HTTP 424 Failed Dependency
	ErrTooEarly                      = NewHTTPError(http.StatusTooEarly)                      // HTTP 425 Too Early
	ErrUpgradeRequired               = NewHTTPError(http.StatusUpgradeRequired)               // HTTP 426 Upgrade Required
	ErrPreconditionRequired          = NewHTTPError(http.StatusPreconditionRequired)          // HTTP 428 Precondition Required
	ErrTooManyRequests               = NewHTTPError(http.StatusTooManyRequests)               // HTTP 429 Too Many Requests
	ErrRequestHeaderFieldsTooLarge   = NewHTTPError(http.StatusRequestHeaderFieldsTooLarge)   // HTTP 431 Request Header Fields Too Large
	ErrUnavailableForLegalReasons    = NewHTTPError(http.StatusUnavailableForLegalReasons)    // HTTP 451 Unavailable For Legal Reasons
	ErrInternalServerError           = NewHTTPError(http.StatusInternalServerError)           // HTTP 500 Internal Server Error
	ErrNotImplemented                = NewHTTPError(http.StatusNotImplemented)                // HTTP 501 Not Implemented
	ErrBadGateway                    = NewHTTPError(http.StatusBadGateway)                    // HTTP 502 Bad Gateway
	ErrServiceUnavailable            = NewHTTPError(http.StatusServiceUnavailable)            // HTTP 503 Service Unavailable
	ErrGatewayTimeout                = NewHTTPError(http.StatusGatewayTimeout)                // HTTP 504 Gateway Timeout
	ErrHTTPVersionNotSupported       = NewHTTPError(http.StatusHTTPVersionNotSupported)       // HTTP 505 HTTP Version Not Supported
	ErrVariantAlsoNegotiates         = NewHTTPError(http.StatusVariantAlsoNegotiates)         // HTTP 506 Variant Also Negotiates
	ErrInsufficientStorage           = NewHTTPError(http.StatusInsufficientStorage)           // HTTP 507 Insufficient Storage
	ErrLoopDetected                  = NewHTTPError(http.StatusLoopDetected)                  // HTTP 508 Loop Detected
	ErrNotExtended                   = NewHTTPError(http.StatusNotExtended)                   // HTTP 510 Not Extended
	ErrNetworkAuthenticationRequired = NewHTTPError(http.StatusNetworkAuthenticationRequired) // HTTP 511 Network Authentication Required

	ErrRendererNotRegistered = errors.New("renderer not registered")
	ErrInvalidRedirectCode   = errors.New("invalid redirect Status code")
)

Functions

func BindData

func BindData(dst any, data map[string][]string, tag string, dataFiles map[string][]*multipart.FileHeader) error

func Debug

func Debug(ctx context.Context) bool

func FileFS

func FileFS[T interface{ FileFS(fs.FS, string) error }](fsys fs.FS, filename string) func(T) error

func NegotiateFormat

func NegotiateFormat(accepted []string, offered ...string) string

func ParseAcceptHeader

func ParseAcceptHeader(acceptHeader string) []string

func ParseAcceptLanguageHeader

func ParseAcceptLanguageHeader(languageHeader string) []string

func RequestLogged

func RequestLogged(ctx context.Context) bool

func RequestLoggerAttrs

func RequestLoggerAttrs[T Resolver](e T, status int, err error) []slog.Attr

func SetHeaderIfMissing

func SetHeaderIfMissing(res http.ResponseWriter, key string, value string)

func StaticFS

func StaticFS[T interface{ StaticFS(fs.FS, bool) error }](fsys fs.FS, indexFallback bool) func(T) error

func WithDebug

func WithDebug(ctx context.Context, debug bool) context.Context

func WithRequestLogged

func WithRequestLogged(ctx context.Context, logged bool) context.Context

func WrapHandler

func WrapHandler[T Resolver](h http.Handler) func(T) error

func WrapMiddleware

func WrapMiddleware[T Resolver](m func(http.Handler) http.Handler) func(T) error

Types

type BindMultipleUnmarshaler

type BindMultipleUnmarshaler interface {
	UnmarshalParams(params []string) error
}

BindMultipleUnmarshaler is used by binder to unmarshal multiple values from request at once to type implementing this interface. For example request could have multiple query fields `?a=1&a=2&b=test` in that case for `a` following slice `["1", "2"] will be passed to unmarshaller.

type BindUnmarshaler

type BindUnmarshaler interface {
	// UnmarshalParam decodes and assigns a value from an form or query param.
	UnmarshalParam(param string) error
}

BindUnmarshaler is the interface used to wrap the UnmarshalParam method. Types that don't implement this, but do implement encoding.TextUnmarshaler will use that interface instead.

type Event

type Event struct {
	hook.Event
	// contains filtered or unexported fields
}

func (*Event) Accept

func (e *Event) Accept() string

Accept returns the value of the Accept header.

func (*Event) AcceptLanguage

func (e *Event) AcceptLanguage() string

AcceptLanguage returns the value of the Accept-Language header.

func (*Event) Accepted

func (e *Event) Accepted() []string

func (*Event) Attachment

func (e *Event) Attachment(fsys fs.FS, file, name string) error

Attachment sends a response as attachment, prompting client to save the file.

func (*Event) BindBody

func (e *Event) BindBody(dst any) error

BindBody binds request body contents to bindable object NB: then binding forms take note that this implementation uses standard library form parsing which parses form data from BOTH URL and BODY if content type is not MIMEMultipartForm See non-MIMEMultipartForm: https://golang.org/pkg/net/http/#Request.ParseForm See MIMEMultipartForm: https://golang.org/pkg/net/http/#Request.ParseMultipartForm

func (*Event) BindHeaders

func (e *Event) BindHeaders(dst any) error

BindHeaders binds HTTP headers to a bindable object

func (*Event) BindQueryParams

func (e *Event) BindQueryParams(dst any) error

BindQueryParams binds query params to bindable object

func (*Event) Blob

func (e *Event) Blob(status int, contentType string, b []byte) error

Blob writes a blob (bytes slice) response.

func (*Event) Context

func (e *Event) Context() context.Context

func (*Event) Cookie

func (e *Event) Cookie(name string) (*http.Cookie, error)

Cookie returns the named cookie provided in the request.

func (*Event) Cookies

func (e *Event) Cookies() []*http.Cookie

Cookies returns the HTTP cookies sent with the request.

func (*Event) Debug

func (e *Event) Debug() bool

func (*Event) FileFS

func (e *Event) FileFS(fsys fs.FS, filename string) error

FileFS serves the specified filename from fsys.

func (*Event) Flush

func (e *Event) Flush() error

Flush flushes buffered data to the current response.

Returns http.ErrNotSupported if e.response doesn't implement the http.Flusher interface (all router package handlers receives a ResponseWriter that implements it unless explicitly replaced with a custom one).

func (*Event) FormFile

func (e *Event) FormFile(name string) (*multipart.FileHeader, error)

FormFile returns the multipart form file for the provided name.

func (*Event) FormParams

func (e *Event) FormParams() (url.Values, error)

FormParams returns the form parameters as `url.Values`.

func (*Event) FormValue

func (e *Event) FormValue(name string) string

FormValue returns the form field value for the provided name.

func (*Event) HTML

func (e *Event) HTML(status int, data string) error

HTML writes an HTML response.

func (*Event) HTMLBlob

func (e *Event) HTMLBlob(status int, b []byte) error

HTMLBlob sends an HTTP blob response with status code.

func (*Event) Inline

func (e *Event) Inline(fsys fs.FS, file, name string) error

Inline sends a response as inline, opening the file in the browser.

func (*Event) IsAjax

func (e *Event) IsAjax() bool

IsAjax returns true if the HTTP request was made with XMLHttpRequest.

func (*Event) IsTLS

func (e *Event) IsTLS() bool

IsTLS reports whether the connection on which the request was received is TLS.

func (*Event) IsWebSocket

func (e *Event) IsWebSocket() bool

IsWebSocket returns true if HTTP connection is WebSocket otherwise false.

func (*Event) JSON

func (e *Event) JSON(status int, i any) error

JSON sends a JSON response with status code.

func (*Event) JSONBlob

func (e *Event) JSONBlob(status int, b []byte) error

func (*Event) JSONP

func (e *Event) JSONP(status int, callback string, i any) error

JSONP sends a JSONP response with status code. It uses `callback` to construct the JSONP payload.

func (*Event) JSONPBlob

func (e *Event) JSONPBlob(status int, callback string, b []byte) error

JSONPBlob sends a JSONP blob response with status code. It uses `callback` to construct the JSONP payload.

func (*Event) JSONPretty

func (e *Event) JSONPretty(status int, i any, indent string) error

JSONPretty sends a pretty-print JSON with status code.

func (*Event) Languages

func (e *Event) Languages() []string

Languages returns a slice of accepted languages from the Accept-Language header.

func (*Event) MultipartForm

func (e *Event) MultipartForm() (*multipart.Form, error)

MultipartForm returns the multipart form.

func (*Event) Negotiate

func (e *Event) Negotiate(status int, data any, offered ...string) error

Negotiate calls different Render according to acceptable Accept format

func (*Event) NegotiateFormat

func (e *Event) NegotiateFormat(offered ...string) string

NegotiateFormat returns an acceptable Accept format.

func (*Event) NoContent

func (e *Event) NoContent(status int) error

NoContent writes a response with no body (ex. 204).

func (*Event) Param

func (e *Event) Param(name string) string

Param returns the value for the named path wildcard in the pattern that matched the request. It returns the empty string if the request was not matched against a pattern or there is no such wildcard in the pattern.

func (*Event) QueryParam

func (e *Event) QueryParam(name string) string

QueryParam returns the query param for the provided name.

func (*Event) QueryParams

func (e *Event) QueryParams() url.Values

QueryParams returns the query parameters as `url.Values`.

func (*Event) QueryString

func (e *Event) QueryString() string

QueryString returns the URL query string.

func (*Event) Redirect

func (e *Event) Redirect(status int, url string) error

Redirect writes a redirect response to the specified url. The status code must be in between 300 – 308 range.

func (*Event) RemoteIP

func (e *Event) RemoteIP() string

RemoteIP returns the IP address of the client that sent the request.

IPv6 addresses are returned expanded. For example, "2001:db8::1" becomes "2001:0db8:0000:0000:0000:0000:0000:0001".

Note that if you are behind reverse proxy(ies), this method returns the IP of the last connecting proxy.

func (*Event) Request

func (e *Event) Request() *http.Request

func (*Event) Reset

func (e *Event) Reset(w *Response, r *http.Request)

func (*Event) Response

func (e *Event) Response() *Response

func (*Event) Scheme

func (e *Event) Scheme() string

Scheme returns the HTTP protocol scheme, `http` or `https`.

func (*Event) SetContext

func (e *Event) SetContext(ctx context.Context)

func (*Event) SetCookie

func (e *Event) SetCookie(cookie *http.Cookie)

SetCookie is an alias for http.SetCookie.

SetCookie adds a Set-Cookie header to the current response's headers. The provided cookie must have a valid Name. Invalid cookies may be silently dropped.

func (*Event) SetDebug

func (e *Event) SetDebug(debug bool)

func (*Event) SetParam

func (e *Event) SetParam(name, value string)

SetParam sets name to value, so that subsequent calls to e.Param(name) return value.

func (*Event) SetRequest

func (e *Event) SetRequest(r *http.Request)

func (*Event) SetResponse

func (e *Event) SetResponse(w *Response)

func (*Event) SetValue

func (e *Event) SetValue(key, value any)

func (*Event) StartTime

func (e *Event) StartTime() time.Time

func (*Event) StaticFS

func (e *Event) StaticFS(fsys fs.FS, indexFallback bool) error

StaticFS serve static directory content from fsys.

If a file resource is missing and indexFallback is set, the request will be forwarded to the base index.html (useful for SPA with pretty urls).

NB! Expects the route to have a "{path...}" wildcard parameter.

Special redirects:

  • if "path" is a file that ends in index.html, it is redirected to its non-index.html version (eg. /test/index.html -> /test/)
  • if "path" is a directory that has index.html, the index.html file is rendered, otherwise if missing - returns 404 or fallback to the root index.html if indexFallback is set

Example:

fsys := os.DirFS("./public")
router.GET("/files/{path...}", StaticFS[*Event](fsys, false))

func (*Event) Status

func (e *Event) Status() int

Status reports the status code of the current response.

func (*Event) Stream

func (e *Event) Stream(status int, contentType string, reader io.Reader) error

Stream streams the specified reader into the response.

func (*Event) String

func (e *Event) String(status int, data string) error

String writes a plain string response.

func (*Event) UserAgent

func (e *Event) UserAgent() string

func (*Event) Value

func (e *Event) Value(key any) any

func (*Event) Written

func (e *Event) Written() bool

Written reports whether the current response has already been written.

func (*Event) XML

func (e *Event) XML(status int, i any) error

XML writes an XML response. It automatically prepends the generic xml.Header string to the response.

func (*Event) XMLBlob

func (e *Event) XMLBlob(status int, b []byte) error

XMLBlob sends an XML blob response with status code.

func (*Event) XMLPretty

func (e *Event) XMLPretty(status int, i any, indent string) error

XMLPretty sends a pretty-print XML with status code.

type EventCleanupFunc

type EventCleanupFunc func()

type EventFactoryFunc

type EventFactoryFunc[T Resolver] func(w *Response, r *http.Request) (T, EventCleanupFunc)

EventFactoryFunc defines the function responsible for creating a Route specific event based on the provided request handler ServeHTTP data.

Optionally return a cleanup function that will be invoked right after the route execution.

type FlushErrorer

type FlushErrorer interface {
	FlushError() error
}

type HTTPError

type HTTPError struct {
	Internal error
	Message  any
	Status   int
	Debug    bool
}

HTTPError represents an error that occurred while handling a request.

func AsHTTPError

func AsHTTPError(err error) *HTTPError

func NewHTTPError

func NewHTTPError(status int, message ...any) *HTTPError

NewHTTPError creates a new HTTPError instance.

func (*HTTPError) Error

func (he *HTTPError) Error() string

Error makes it compatible with `error` interface.

func (*HTTPError) MarshalJSON

func (he *HTTPError) MarshalJSON() ([]byte, error)

func (*HTTPError) SetInternal

func (he *HTTPError) SetInternal(err error) *HTTPError

SetInternal sets error to HTTPError.Internal

func (*HTTPError) SetMessage

func (he *HTTPError) SetMessage(message any) *HTTPError

SetMessage sets message to HTTPError.Message

func (*HTTPError) ToMap

func (he *HTTPError) ToMap() map[string]any

func (*HTTPError) Unwrap

func (he *HTTPError) Unwrap() error

Unwrap satisfies the Go 1.13 error wrapper interface.

func (*HTTPError) WithInternal

func (he *HTTPError) WithInternal(err error) *HTTPError

WithInternal returns clone of HTTPError with err set to HTTPError.Internal field

func (*HTTPError) WithMessage

func (he *HTTPError) WithMessage(message any) *HTTPError

WithMessage returns clone of HTTPError with message set to HTTPError.Message field

type HTTPErrorHandler

type HTTPErrorHandler[T Resolver] func(T, error)

func ErrorHandler

func ErrorHandler[T Resolver](render func(T, *HTTPError), mapper func(error) *HTTPError, logger *slog.Logger) HTTPErrorHandler[T]

type RWUnwrapper

type RWUnwrapper interface {
	Unwrap() http.ResponseWriter
}

RWUnwrapper specifies that a http.ResponseWriter could be "unwrapped" (usually used with http.ResponseController).

type RedirectError

type RedirectError struct {
	Status int
	URL    string
}

func NewFoundRedirectError

func NewFoundRedirectError(url string) *RedirectError

func NewPermanentlyRedirectError

func NewPermanentlyRedirectError(url string) *RedirectError

func (*RedirectError) Error

func (r *RedirectError) Error() string

type Resolver

type Resolver interface {
	hook.Resolver

	SetRequest(r *http.Request)
	Request() *http.Request

	SetResponse(w *Response)
	Response() *Response
}

type Response

type Response struct {
	http.ResponseWriter

	Written   bool
	Buffering bool
	Status    int
	Size      int64
	// contains filtered or unexported fields
}

Response wraps an http.ResponseWriter and implements its interface to be used by an HTTP handler to construct an HTTP response. See: https://golang.org/pkg/net/http/#ResponseWriter

func NewResponse

func NewResponse(w http.ResponseWriter) *Response

NewResponse creates a new instance of Response.

func (*Response) After

func (r *Response) After(fn func())

After registers a function which is called just after the response is Written. If the `Content-Length` is unknown, none of the after function is executed.

func (*Response) Before

func (r *Response) Before(fn func())

Before registers a function which is called just before the response is Written.

func (*Response) Buffer

func (r *Response) Buffer() []byte

func (*Response) Flush

func (r *Response) Flush()

Flush implements the http.Flusher interface to allow an HTTP handler to flush buffered data to the client. See http.Flusher(https://golang.org/pkg/net/http/#Flusher)

func (*Response) FlushError

func (r *Response) FlushError() error

FlushError is similar to [Flush] but returns http.ErrNotSupported if the wrapped writer doesn't support it.

func (*Response) Hijack

func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack implements the http.Hijacker interface to allow an HTTP handler to take over the connection. See http.Hijacker(https://golang.org/pkg/net/http/#Hijacker)

func (*Response) Push

func (r *Response) Push(target string, opts *http.PushOptions) error

Push implements http.Pusher to indicate HTTP/2 server push support.

func (*Response) ReadFrom

func (r *Response) ReadFrom(reader io.Reader) (n int64, err error)

ReadFrom implements io.ReaderFrom by checking if the underlying writer supports it. Otherwise calls io.Copy.

func (*Response) Reset

func (r *Response) Reset(w http.ResponseWriter)

func (*Response) Unwrap

func (r *Response) Unwrap() http.ResponseWriter

Unwrap returns the original http.ResponseWriter. ResponseController can be used to access the original http.ResponseWriter. See [https://go.dev/blog/go1.20]

func (*Response) Write

func (r *Response) Write(b []byte) (n int, err error)

Write writes the data to the connection as part of an HTTP reply.

func (*Response) WriteHeader

func (r *Response) WriteHeader(status int)

WriteHeader sends an HTTP response header with Status code. If WriteHeader is not called explicitly, the first call to Write will trigger an implicit WriteHeader(http.StatusOK). Thus explicit calls to WriteHeader are mainly used to send error codes.

type Route

type Route[T hook.Resolver] struct {
	Method      string
	Path        string
	Action      func(T) error
	Middlewares []*hook.Handler[T]
	// contains filtered or unexported fields
}

func (*Route[T]) Bind

func (route *Route[T]) Bind(middlewares ...*hook.Handler[T]) *Route[T]

Bind registers one or multiple middleware handlers to the current route.

func (*Route[T]) BindFunc

func (route *Route[T]) BindFunc(middlewareFuncs ...func(e T) error) *Route[T]

BindFunc registers one or multiple middleware functions to the current route.

The registered middleware functions are "anonymous" and with default priority, aka. executes in the order they were registered.

If you need to specify a named middleware (ex. so that it can be removed) or middleware with custom exec prirority, use the Route.Bind method.

func (*Route[T]) Unbind

func (route *Route[T]) Unbind(middlewareIDs ...string) *Route[T]

Unbind removes one or more middlewares with the specified id(s) from the current route.

It also adds the removed middleware ids to an exclude list so that they could be skipped from the execution chain in case the middleware is registered in a parent group.

Anonymous middlewares are considered non-removable, aka. this method does nothing if the middleware id is an empty string.

type Router

type Router[T Resolver] struct {
	*RouterGroup[T]
	// contains filtered or unexported fields
}

func New

func New[T Resolver](eventFactory EventFactoryFunc[T], errorHandler HTTPErrorHandler[T]) *Router[T]

func (*Router[T]) Build

func (r *Router[T]) Build(mux *http.ServeMux) (http.Handler, error)

Build constructs a new http.Handler instance from the current router configurations.

func (*Router[T]) Patterns

func (r *Router[T]) Patterns() iter.Seq[string]

func (*Router[T]) Pre

func (r *Router[T]) Pre(middlewares ...*hook.Handler[T])

func (*Router[T]) PreFunc

func (r *Router[T]) PreFunc(middlewareFuncs ...func(e T) error)

type RouterGroup

type RouterGroup[T hook.Resolver] struct {
	Prefix      string
	Middlewares []*hook.Handler[T]
	// contains filtered or unexported fields
}

func (*RouterGroup[T]) Any

func (group *RouterGroup[T]) Any(path string, action func(e T) error) *Route[T]

Any is a shorthand for RouterGroup.Route with "" as route method (aka. matches any method).

func (*RouterGroup[T]) Bind

func (group *RouterGroup[T]) Bind(middlewares ...*hook.Handler[T]) *RouterGroup[T]

Bind registers one or multiple middleware handlers to the current group.

func (*RouterGroup[T]) BindFunc

func (group *RouterGroup[T]) BindFunc(middlewareFuncs ...func(e T) error) *RouterGroup[T]

BindFunc registers one or multiple middleware functions to the current group.

The registered middleware functions are "anonymous" and with default priority, aka. executes in the order they were registered.

If you need to specify a named middleware (ex. so that it can be removed) or middleware with custom exec priority, use RouterGroup.Bind method.

func (*RouterGroup[T]) DELETE

func (group *RouterGroup[T]) DELETE(path string, action func(e T) error) *Route[T]

DELETE is a shorthand for RouterGroup.Route with DELETE as route method.

func (*RouterGroup[T]) GET

func (group *RouterGroup[T]) GET(path string, action func(e T) error) *Route[T]

GET is a shorthand for RouterGroup.Route with GET as route method.

func (*RouterGroup[T]) Group

func (group *RouterGroup[T]) Group(prefix string) *RouterGroup[T]

Group creates and register a new child RouterGroup into the current one with the specified prefix.

The prefix follows the standard Go net/http ServeMux pattern format ("[HOST]/[PATH]") and will be concatenated recursively into the final route path, meaning that only the root level group could have HOST as part of the prefix.

Returns the newly created group to allow chaining and registering sub-routes and group specific middlewares.

func (*RouterGroup[T]) HEAD

func (group *RouterGroup[T]) HEAD(path string, action func(e T) error) *Route[T]

HEAD is a shorthand for RouterGroup.Route with HEAD as route method.

func (*RouterGroup[T]) OPTIONS

func (group *RouterGroup[T]) OPTIONS(path string, action func(e T) error) *Route[T]

OPTIONS is a shorthand for RouterGroup.Route with OPTIONS as route method.

func (*RouterGroup[T]) PATCH

func (group *RouterGroup[T]) PATCH(path string, action func(e T) error) *Route[T]

PATCH is a shorthand for RouterGroup.Route with PATCH as route method.

func (*RouterGroup[T]) POST

func (group *RouterGroup[T]) POST(path string, action func(e T) error) *Route[T]

POST is a shorthand for RouterGroup.Route with POST as route method.

func (*RouterGroup[T]) PUT

func (group *RouterGroup[T]) PUT(path string, action func(e T) error) *Route[T]

PUT is a shorthand for RouterGroup.Route with PUT as route method.

func (*RouterGroup[T]) Route

func (group *RouterGroup[T]) Route(method string, path string, action func(e T) error) *Route[T]

Route registers a single route into the current group.

Note that the final route path will be the concatenation of all parent groups prefixes + the route path. The path follows the standard Go net/http ServeMux format ("[HOST]/[PATH]"), meaning that only a top level group route could have HOST as part of the prefix.

Returns the newly created route to allow attaching route-only middlewares.

func (*RouterGroup[T]) SEARCH

func (group *RouterGroup[T]) SEARCH(path string, action func(e T) error) *Route[T]

SEARCH is a shorthand for RouterGroup.Route with SEARCH as route method.

func (*RouterGroup[T]) Unbind

func (group *RouterGroup[T]) Unbind(middlewareIDs ...string) *RouterGroup[T]

Unbind removes one or more middlewares with the specified id(s) from the current group and its children (if any).

Anonymous middlewares are not removable, aka. this method does nothing if the middleware id is an empty string.

Directories

Path Synopsis
adapter module
internal
arr

Jump to

Keyboard shortcuts

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