breeze

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: MIT Imports: 19 Imported by: 0

README

🌀 Breeze — High-Performance Golang Web Framework

Go Reference Go Report Card License

Breeze is a fast, lightweight, and modern Go web framework designed for simplicity, flexibility, and high performance. Build secure, maintainable web applications with ease. 🌟


✨ Features

  • 🏎️ High-performance routing
  • 🛡️ Middleware support for auth, security, compression, caching, CORS, rate limiting, etc.
  • 📦 Helpers for JSON, HTML, string responses
  • 🔐 Security headers middleware (CSP, HSTS, XSS protection)
  • 🔑 JWT authentication & refresh token support
  • ⏱️ Rate limiting & throttling
  • ♻️ Panic recovery to keep your server alive
  • 📈 Optional ETag / in-memory caching

🚀 Installation

go get github.com/nelthaarion/breeze

🏁 Quick Start

package main

import (
	"github.com/nelthaarion/breeze"
	"github.com/nelthaarion/breeze/middleware"
)

func main() {
	router := breeze.NewRouter()

	// 🌐 Global security middleware
	router.Use(middleware.DefaultSecurityMiddleware())

	// 🔐 Route-specific middleware: JWT authentication
	router.Handle("GET", "/profile", profileHandler, middleware.JWTAuthMiddleware(middleware.JWTOptions{
		AccessSecret:       "access_secret",
		RefreshSecret:      "refresh_secret",
		EnableRefreshToken: true,
		RequiredRoles:      []string{"user", "admin"},
	}))

	// 🚀 Start server
	router.Listen(":8080")
}

func profileHandler(ctx *breeze.Context) {
	user := ctx.GetParam("user") // claims set by JWT middleware
	ctx.JSON(map[string]string{
		"message": "Welcome " + user + " 🌟",
	})
}

🧩 Middleware

Middlewares in Breeze are just HandlerFuncs. They can be applied:

  • Globally with router.Use()
  • Per-route with router.Handle()
🔹 Built-in Middlewares
Middleware Description
🛡️ Security Adds headers like CSP, HSTS, X-Frame-Options, XSS-Protection
🔑 JWT Auth Validates access & refresh tokens, supports roles and claims validation
♻️ Recovery Catches panics in handlers or middleware
⏱️ Rate Limiting Limits requests per client IP
🌍 CORS Handles cross-origin requests
🗜️ Compression Supports gzip, deflate, brotli
🏷️ ETag / Caching Adds ETag, conditional GET, optional in-memory caching

👨‍💻 User Use Case: Middleware Chaining

Imagine a profile endpoint that requires:

  1. Authenticated user (JWT)
  2. Safe security headers
  3. Panic-safe execution
router.Handle("GET", "/profile", profileHandler,
	middleware.RecoveryMiddleware(),
	middleware.DefaultSecurityMiddleware(),
	middleware.JWTAuthMiddleware(middleware.JWTOptions{
		AccessSecret:  "access_secret",
		RefreshSecret: "refresh_secret",
		RequiredRoles: []string{"user", "admin"},
	}),
)

Flow:

  1. ♻️ RecoveryMiddleware() – prevents crashes
  2. 🛡️ DefaultSecurityMiddleware() – adds headers
  3. 🔑 JWTAuthMiddleware() – validates tokens, sets claims in ctx.params

Inside profileHandler:

func profileHandler(ctx *breeze.Context) {
	user := ctx.GetParam("user") // safely access JWT claims
	ctx.JSON(map[string]string{
		"message": "Welcome " + user + " 🌟",
	})
}

💡 Tips & Tricks

  • Use ctx.SetParam & ctx.GetParam to safely store/retrieve per-request data
  • Chain multiple middlewares for fine-grained control
  • Combine global and per-route middleware for flexible security policies
  • Use refresh tokens to automatically renew JWT access tokens

🎨 Summary

Breeze makes Go web development:

  • ✅ Fast
  • ✅ Secure
  • ✅ Extensible
  • ✅ Fun

Build your next Go API, microservice, or web app the Breeze way! 🌬️

🧑‍💻 Contributing

Contributions are welcome! Please open issues and pull requests for new features, bug fixes, and optimizations.


📄 License

MIT License © 2025 Farhsad Khazaei Fard(https://github.com/nelthaarion)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Breeze

type Breeze struct {
	*gnet.BuiltinEventEngine
	Router *Router

	Pool *WorkerPool
	// contains filtered or unexported fields
}

Breeze is the main server struct, embedding gnet's event engine.

Performance decisions:

  • s.mu + s.Bufs[fd] uses per-connection buffering. The single mutex creates contention between gnet reactors when multicore=true. We mitigate this with sync.Map so each fd's read/write is independent.
  • buf reslicing (buf = buf[consumed:]) kept the full backing array alive, leaking memory under pipelining. We now compact: when leftover bytes are small we copy them to a fresh slice so the large receive buffer can be GC'd.
  • The exec closure captures ctx and c by value so the goroutine/worker doesn't pin the loop variable across iterations.

func New

func New(router *Router, pool *WorkerPool) *Breeze

func (*Breeze) OnClose added in v1.0.1

func (s *Breeze) OnClose(c gnet.Conn, err error) gnet.Action

OnClose cleans up the per-connection buffer when a connection closes.

func (*Breeze) OnTraffic

func (s *Breeze) OnTraffic(c gnet.Conn) gnet.Action

func (*Breeze) Run

func (s *Breeze) Run(port int, multiCore bool) error

type Context

type Context struct {
	Conn gnet.Conn
	Req  *HTTPRequest
	Res  *HTTPResponse
	// contains filtered or unexported fields
}

func (*Context) Abort

func (ctx *Context) Abort()

func (*Context) GetParam added in v0.1.3

func (ctx *Context) GetParam(key string) string

func (*Context) GetParams added in v0.1.3

func (ctx *Context) GetParams() map[string]string

func (*Context) HTML added in v0.1.2

func (ctx *Context) HTML(data []byte)

func (*Context) JSON

func (ctx *Context) JSON(data any)

func (*Context) Next

func (ctx *Context) Next()

func (*Context) Param

func (ctx *Context) Param(key string) string

func (*Context) ParseMultipart

func (ctx *Context) ParseMultipart(maxFileSize int64) (map[string][]*UploadedFile, map[string][]string, error)

ParseMultipart stores parsed files and fields into context (so handlers can reuse). It returns files and fields same as req.ParseMultipart.

func (*Context) Query

func (ctx *Context) Query(key string) string

func (*Context) SaveUploadedFile

func (ctx *Context) SaveUploadedFile(fieldName, destPath string, maxFileSize int64) (string, error)

SaveUploadedFile saves the first uploaded file from fieldName to destPath using ctx.Req. Returns the original filename and error if any.

func (*Context) SetHeader added in v0.1.3

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

SetHeader adds or replaces a single response header.

When the response was built via JSON/WriteString/HTML, its Headers field points to a shared package-level map. SetHeader detects this via the headersShared flag and performs a copy-on-write before mutating, so the shared maps are never clobbered. Subsequent SetHeader calls on the same response are direct writes into the private copy.

func (*Context) SetParam added in v0.1.3

func (ctx *Context) SetParam(key, value string)

func (*Context) SetParams added in v0.1.3

func (ctx *Context) SetParams(p map[string]string)

func (*Context) Status

func (ctx *Context) Status(code int)

Status sets (or overrides) the response status code. For bodyless responses (204, 304) call this alone. For responses with a body, call the body method first (JSON/WriteString/HTML), then call Status — those methods replace ctx.Res entirely.

func (*Context) WriteString

func (ctx *Context) WriteString(s string)

type HTTPRequest

type HTTPRequest struct {
	Method Method
	Path   string
	Query  url.Values
	Header map[string]string
	Body   []byte
}

HTTPRequest holds parsed HTTP request data.

func ParseHTTPRequest

func ParseHTTPRequest(data []byte) (*HTTPRequest, int, error)

ParseHTTPRequest parses raw bytes into an HTTPRequest.

Performance decisions:

  • b2s converts []byte → string with zero allocation (safe here because the string is only used within this function or stored in a map whose backing bytes outlive the function).
  • We scan the request-line manually instead of bytes.Split to avoid allocating a [][]byte for the header lines.
  • Header keys are lowercased in-place on a stack buffer up to 64 bytes.

func (*HTTPRequest) ParseMultipart

func (req *HTTPRequest) ParseMultipart(maxFileSize int64) (map[string][]*UploadedFile, map[string][]string, error)

ParseMultipart parses a multipart/form-data request body and returns: - files: map[field][]*UploadedFile - fields: map[field][]string (other non-file form fields) If a file is bigger than maxFileSize, an error is returned for that part. Pass maxFileSize as 0 to allow unlimited (not recommended).

This function DOES NOT use http.Request; it operates on your HTTPRequest struct.

func (*HTTPRequest) SaveUploadedFileFromRequest

func (req *HTTPRequest) SaveUploadedFileFromRequest(fieldName, destPath string, maxFileSize int64) (string, error)

SaveUploadedFileFromRequest parses the multipart form and saves the first file from fieldName to destPath. maxFileSize limits each file size in bytes (0 = unlimited). Returns the saved filename (original) and error if any.

type HTTPResponse

type HTTPResponse struct {
	Status  int
	Headers map[string]string
	Body    []byte
	// contains filtered or unexported fields
}

HTTPResponse represents an HTTP response.

func (*HTTPResponse) Bytes

func (r *HTTPResponse) Bytes() []byte

Bytes serializes the HTTPResponse to raw HTTP/1.1 bytes.

Performance decisions:

  • No fmt.Sprintf: we use strconv.AppendInt for the status code and content-length, which writes directly into the buffer.
  • We pre-size the buffer to avoid growth reallocations for typical responses.
  • The status text lookup is a direct array index — O(1), no map hash.

type HandlerFunc

type HandlerFunc func(*Context)

type Method

type Method string

Method defines the HTTP method type (GET, POST, etc.).

const (
	GET    Method = "GET"
	PUT    Method = "PUT"
	PATCH  Method = "PATCH"
	POST   Method = "POST"
	DELETE Method = "DELETE"
	OPTION Method = "OPTION"
)

type Router

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

func NewRouter

func NewRouter() *Router

func (*Router) Find

func (r *Router) Find(req *HTTPRequest) (HandlerFunc, []HandlerFunc, map[string]string)

Find matches the incoming request to a registered route.

Performance decisions:

  • Path splitting uses a manual scanner instead of strings.Split so we can bail out early (wrong segment count) with zero allocations on a miss.
  • The params map is only allocated when the route actually has :param segments, and is pre-sized to paramCount.
  • paramIndex[] is a pre-computed bool slice so we avoid strings.HasPrefix inside the hot matching loop.

func (*Router) Handle

func (r *Router) Handle(method Method, pattern string, handler HandlerFunc, middlewares ...HandlerFunc)

func (*Router) Routes added in v1.0.1

func (r *Router) Routes() []*route

func (*Router) ServeStatic added in v0.1.2

func (r *Router) ServeStatic(prefix, root string)

ServeStatic registers handlers to serve files under `root` at URL prefix `prefix`. Example: ServeStatic("/static", "./public") will serve ./public/* at /static/*

func (*Router) SetStaticDir added in v0.1.2

func (r *Router) SetStaticDir(dir string)

func (*Router) Use

func (r *Router) Use(mw ...HandlerFunc)

type UploadedFile

type UploadedFile struct {
	Field       string               // form field name
	Filename    string               // uploaded filename
	Header      textproto.MIMEHeader // original part headers
	ContentType string               // detected content type (from header or sniff)
	Size        int64                // size in bytes
	Content     []byte               // file bytes (nil if streamed)
}

UploadedFile holds a parsed uploaded file's metadata and content.

type WorkerPool

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

func NewWorkerPool

func NewWorkerPool(concurrency int) *WorkerPool

NewWorkerPool creates a pool with `concurrency` goroutines and a task queue of concurrency × defaultChannelMultiplier to absorb request bursts without blocking gnet's event loops.

func (*WorkerPool) Shutdown

func (p *WorkerPool) Shutdown(ctx context.Context)

Shutdown waits for all in-flight tasks to complete or for ctx to expire.

func (*WorkerPool) Submit

func (p *WorkerPool) Submit(f func())

Submit enqueues a task. It never blocks as long as the queue has capacity; if the queue is full it falls back to spawning a goroutine so the event loop is never stalled.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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