aero

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Mar 30, 2026 License: MIT Imports: 21 Imported by: 0

README

Aero

Blazing fast, zero-dependency, lightweight web framework for Go.

Features

  • Zero dependencies, pure stdlib, no transitive vulnerabilities
  • Zero allocations in the hot path
  • Faster than net/http 1.8x throughput, 60x less memory per request
  • Auto HTTP2 support
  • Hybrid routing with O(1) static map for exact paths, Segment Trie for dynamic ones
  • Order-sensitive middleware

Guide

Installation
go get github.com/Alsond5/aero

Requires Go 1.25+

Using
package main

import (
    "github.com/Alsond5/aero"
)

func Logger(c *aero.Ctx) error {
	start := time.Now()
	err := c.Next()
	duration := time.Since(start)

	slog.Info("request",
		"method", c.Method(),
		"path", c.Path(),
		"ip", c.IP(),
		"duration", duration,
		"status", c.ResponseStatus(),
	)

	return err
}

func main() {
    app := aero.New()

    app.Use(Logger)

    app.GET("/api/users/:id", func(c *aero.Ctx) error {
        id := c.Param("id")
        return c.JSON(map[string]string{"id": id})
    })

    app.Listen(":8080")
}

Benchmarks

Machine: Intel Core i7-10750H (unplugged, low-power mode) Go: 1.25 OS: Fedora Linux, amd64 Test: 1 middleware + 2 GET routes (1 dynamic, 1 static) + 1 POST route with JSON body parse

Standart
Framework ns/op B/op allocs/op req/s
Aero 603.8 339 3 1,656,177
Echo v5 772.7 336 4 1,294,163
net/http 727.9 333 4 1,373,815
Gin v1 955.2 368 5 1,046,901
Chi v5 1442.7 808 6 693,144
Routing
Framework ns/op B/op allocs/op req/s
Aero 194.8 0 0 5,133,470
Echo v5 232.6 16 1 4,299,226
net/http 242.2 20 1 4,128,819
Gin v1 277.6 52 2 3,602,305
Chi v5 1109.8 548 4 901,063
Parallel (12 goroutines)
Framework ns/op B/op allocs/op req/s
Aero 36.2 0 0 27,624,309
Echo v5 46.3 16 1 21,598,272
net/http 60.2 20 1 16,611,295
Gin v1 61.2 52 2 16,339,869
Chi v5 179.7 548 4 5,564,830

Design Decisions

Every feature is built on the Go standard library. No transitive vulnerabilities, no version conflicts, no go mod tidy surprises.

URL routing operates on path segments, not individual bytes. Radix Tree compression offers no benefit at segment granularity. A Segment Trie with a static map fast-path is simpler and equally fast.

Global middleware is stored once on the App. Routes store only an integer (middlewareCount). At dispatch time, the middleware slice and route handlers are indexed directly. No copying, no appending.

FastHTTP offers raw performance gains but breaks compatibility with the standard http.Handler ecosystem. Aero stays on net/http and achieves zero-alloc performance through careful design rather than a custom HTTP stack.

License

MIT License

Documentation

Index

Constants

View Source
const (
	RangeUnsatisfiable = -1
	RangeMalformed     = -2
)
View Source
const (
	HeaderTransferEncoding    = "Transfer-Encoding"
	HeaderContentType         = "Content-Type"
	HeaderContentLength       = "Content-Length"
	HeaderLink                = "Link"
	HeaderContentDisposition  = "Content-Disposition"
	HeaderXContentTypeOptions = "X-Content-Type-Options"
	HeaderReferer             = "Referer"
	HeaderLocation            = "Location"
	HeaderVary                = "Vary"
	HeaderCacheControl        = "Cache-Control"
)
View Source
const (
	MB int64 = 1 << 20
)
View Source
const (
	Version = "0.4.0"
)

Variables

View Source
var (
	ErrBodyAlreadyRead      = errors.New("aero: request body already read")
	ErrBodyTooLarge         = errors.New("aero: request body too large")
	ErrBodyEmpty            = errors.New("aero: request body is empty")
	ErrFormAlreadyParsed    = errors.New("aero: form already parsed")
	ErrNotMultipart         = errors.New("aero: content type is not multipart/form-data")
	ErrRangeNotPresent      = errors.New("aero: Range header not present")
	ErrRangeUnsatisfiable   = errors.New("aero: range not satisfiable")
	ErrRangeMalformed       = errors.New("aero: range header malformed")
	ErrUnsupportedMediaType = errors.New("aero: unsupported content encoding")
)
View Source
var (
	ErrFileNotFound    = errors.New("aero: file not found")
	ErrIsDirectory     = errors.New("aero: path is a directory")
	ErrPathRequired    = errors.New("aero: path is required")
	ErrPathNotAbsolute = errors.New("aero: path must be absolute or root must be specified")
)
View Source
var ErrTLSCertRequired = errors.New("aero: TLS cert and key are required")

Functions

This section is empty.

Types

type App

type App struct {
	NotFoundHandler         NotFoundHandler
	MethodNotAllowedHandler MethodNotAllowedHandler
	ErrorHandler            ErrorHandler
	OptionsHandler          OptionsHandler
	// contains filtered or unexported fields
}

func New

func New(config ...Config) *App

func (*App) DELETE

func (a *App) DELETE(path string, handlers ...HandlerFunc)

func (*App) GET

func (a *App) GET(path string, handlers ...HandlerFunc)

func (*App) Group added in v0.4.0

func (a *App) Group(prefix string, m ...HandlerFunc) (g *Group)

func (*App) HEAD

func (a *App) HEAD(path string, handlers ...HandlerFunc)

func (*App) Listen

func (a *App) Listen(addr string) error

func (*App) ListenTLS

func (a *App) ListenTLS(addr, cert, key string) error

func (*App) OPTIONS

func (a *App) OPTIONS(path string, handlers ...HandlerFunc)

func (*App) PATCH

func (a *App) PATCH(path string, handlers ...HandlerFunc)

func (*App) POST

func (a *App) POST(path string, handlers ...HandlerFunc)

func (*App) PUT

func (a *App) PUT(path string, handlers ...HandlerFunc)

func (*App) ServeHTTP

func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*App) Use

func (a *App) Use(handlers ...HandlerFunc)

type Config

type Config struct {
	TrustProxy         bool
	SubdomainOffset    int
	MaxBodySize        int64
	MaxMultipartMemory int64
}

type CookieOptions

type CookieOptions struct {
	MaxAge   int
	Path     string
	Domain   string
	Secure   bool
	HttpOnly bool
	SameSite http.SameSite
}

type Ctx

type Ctx struct {
	Req
	Res
	// contains filtered or unexported fields
}

func (*Ctx) Next

func (c *Ctx) Next() error

type ErrorHandler added in v0.2.0

type ErrorHandler func(c *Ctx, err error)

type Group added in v0.4.0

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

func (*Group) DELETE added in v0.4.0

func (g *Group) DELETE(path string, handlers ...HandlerFunc)

func (*Group) GET added in v0.4.0

func (g *Group) GET(path string, handlers ...HandlerFunc)

func (*Group) Group added in v0.4.0

func (g *Group) Group(prefix string, m ...HandlerFunc) (group *Group)

func (*Group) HEAD added in v0.4.0

func (g *Group) HEAD(path string, handlers ...HandlerFunc)

func (*Group) OPTIONS added in v0.4.0

func (g *Group) OPTIONS(path string, handlers ...HandlerFunc)

func (*Group) PATCH added in v0.4.0

func (g *Group) PATCH(path string, handlers ...HandlerFunc)

func (*Group) POST added in v0.4.0

func (g *Group) POST(path string, handlers ...HandlerFunc)

func (*Group) PUT added in v0.4.0

func (g *Group) PUT(path string, handlers ...HandlerFunc)

func (*Group) Use added in v0.4.0

func (g *Group) Use(middleware ...HandlerFunc)

type HandlerFunc

type HandlerFunc func(c *Ctx) error

type MethodNotAllowedHandler added in v0.2.0

type MethodNotAllowedHandler func(allowed string, c *Ctx)

type NotFoundHandler added in v0.2.0

type NotFoundHandler func(c *Ctx)

type OptionsHandler added in v0.3.0

type OptionsHandler func(allowed string, c *Ctx)

type Param

type Param struct {
	Key   string
	Value string
}

type ParamValues

type ParamValues [maxParamCount]Param

type Range

type Range struct {
	Start int64
	End   int64
}

type RangeResult

type RangeResult struct {
	Type   string
	Ranges []Range
}

type Req

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

func (*Req) Accepts

func (req *Req) Accepts(types ...string) string

func (*Req) AcceptsCharsets

func (req *Req) AcceptsCharsets(charsets ...string) string

func (*Req) AcceptsEncodings

func (req *Req) AcceptsEncodings(encodings ...string) string

func (*Req) AcceptsLanguages

func (req *Req) AcceptsLanguages(langs ...string) string

func (*Req) BaseURL

func (req *Req) BaseURL() string

func (*Req) Body

func (r *Req) Body() ([]byte, error)

func (*Req) BodyJSON

func (req *Req) BodyJSON(v any) error

func (*Req) BodyReader

func (r *Req) BodyReader() (io.ReadCloser, error)

func (*Req) Context

func (req *Req) Context() context.Context

func (*Req) Cookie

func (req *Req) Cookie(name string) (*http.Cookie, error)

func (*Req) Cookies

func (req *Req) Cookies() []*http.Cookie

func (*Req) FormFile

func (req *Req) FormFile(key string) (multipart.File, *multipart.FileHeader, error)

func (*Req) FormFiles

func (req *Req) FormFiles(key string) ([]*multipart.FileHeader, error)

func (*Req) FormValue

func (req *Req) FormValue(key string) string

func (*Req) FormValues

func (req *Req) FormValues() map[string][]string

func (*Req) Fresh

func (req *Req) Fresh() bool

func (*Req) Get

func (req *Req) Get(name string) string

func (*Req) Header

func (req *Req) Header(name string) string

func (*Req) Headers

func (req *Req) Headers() http.Header

func (*Req) Host

func (req *Req) Host() string

func (*Req) Hostname

func (req *Req) Hostname() string

func (*Req) IP

func (req *Req) IP() string

func (*Req) IPs

func (req *Req) IPs() []string

func (*Req) Method

func (req *Req) Method() string

func (*Req) MultipartReader

func (req *Req) MultipartReader() (*multipart.Reader, error)

func (*Req) OriginalURL

func (req *Req) OriginalURL() string

func (*Req) Param

func (req *Req) Param(key string) string

func (*Req) Params

func (req *Req) Params() []Param

func (*Req) Path

func (req *Req) Path() string

func (*Req) Protocol

func (req *Req) Protocol() string

func (*Req) Query

func (req *Req) Query(key string) string

func (*Req) QueryAll

func (req *Req) QueryAll() url.Values

func (*Req) Range

func (req *Req) Range(size int64, combine ...bool) (*RangeResult, error)

func (*Req) Secure

func (req *Req) Secure() bool

func (*Req) Stale

func (req *Req) Stale() bool

func (*Req) Subdomains

func (req *Req) Subdomains() []string

func (*Req) XHR

func (req *Req) XHR() bool

type Res

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

func (*Res) AddHeader

func (res *Res) AddHeader(key, value string) *Res

func (*Res) Attachment

func (res *Res) Attachment(filename ...string) *Res

func (*Res) ClearCookie

func (res *Res) ClearCookie(name string, opts ...CookieOptions) *Res

func (*Res) DeleteHeader

func (res *Res) DeleteHeader(key string) *Res

func (*Res) Download

func (res *Res) Download(path string, filename ...string) error

func (*Res) DownloadFS

func (res *Res) DownloadFS(fsys http.FileSystem, path string, filename ...string) error

func (*Res) Format

func (res *Res) Format(handlers map[string]func() error) error

func (*Res) GetHeader

func (res *Res) GetHeader(key string) string

func (*Res) JSON

func (res *Res) JSON(body any) error

func (*Res) JSONP

func (res *Res) JSONP(body any, callback string) error
func (res *Res) Links(links map[string]string) *Res

func (*Res) Location

func (res *Res) Location(url string) *Res

func (*Res) Redirect

func (res *Res) Redirect(url string, code ...int) error

func (*Res) ResponseStatus

func (res *Res) ResponseStatus() int

func (*Res) Send

func (res *Res) Send(body any) error

func (*Res) SendBytes

func (res *Res) SendBytes(body []byte) error

func (*Res) SendFile

func (res *Res) SendFile(path string, opts ...SendFileOptions) error

func (*Res) SendFileFS

func (res *Res) SendFileFS(fsys http.FileSystem, path string) error

func (*Res) SendStatus

func (res *Res) SendStatus(code int) error

func (*Res) SendString

func (res *Res) SendString(body string) error

func (*Res) SetCookie

func (res *Res) SetCookie(name, value string, opts ...CookieOptions) *Res

func (*Res) SetHeader

func (res *Res) SetHeader(key, value string) *Res

func (*Res) Status

func (res *Res) Status(code int) *Res

func (*Res) Type

func (res *Res) Type(t string) *Res

func (*Res) Vary

func (res *Res) Vary(field string) *Res

type Router

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

func NewRouter added in v0.2.0

func NewRouter() *Router

type SendFileOptions

type SendFileOptions struct {
	MaxAge  int
	Headers map[string]string
	Root    string
}

type ServerConfig

type ServerConfig struct {
	Addr            string
	Listener        net.Listener
	TLSCert         string
	TLSKey          string
	GracefulTimeout time.Duration
	OnShutdownError func(err error)
}

func (ServerConfig) Start

func (sc ServerConfig) Start(ctx context.Context, app *App) error

func (ServerConfig) StartTLS

func (sc ServerConfig) StartTLS(ctx context.Context, app *App) error

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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