Fiber — Architecture#
Architectural style#
Middleware-chain framework (Layered + Plugin-based Library)
Fiber is an HTTP web framework modeled on Express.js. Its architecture is a classic middleware pipeline layered on top of a high-performance HTTP engine (fasthttp). It is not a monolith or a microservice — it is a library that applications embed. The architectural style can be described as:
- Layered — there is a clear bottom-to-top stack: fasthttp engine → App/Router core → Ctx abstraction → Handler/Middleware chain → user code.
- Plugin-based — middleware is first-class. The 30+ bundled middleware packages all conform to the
Handler = func(Ctx) errortype and attach to the pipeline viaapp.Use()or method-specific route registration. - Interface-driven extensibility — key abstractions (
Ctx,Router,Storage,Service,Views,CustomBinder) are interfaces, allowing users to swap implementations without modifying the framework.
Evidence: app.requestHandler in router.go:315 is the fasthttp callback — it acquires a pooled Ctx, dispatches to app.next(), which walks the route/middleware stack. Every piece of user logic, middleware, and error recovery flows through this single handler function.
Component diagram (textual)#
┌─────────────────────────────────────────────────────────────┐
│ User Application │
│ fiber.New() → app.Use(mw) → app.Get("/path", handler) │
└────────────────────────┬────────────────────────────────────┘
│ registers routes/middleware
▼
┌─────────────────────────────────────────────────────────────┐
│ App (app.go) │
│ Config · Hooks · State · mountFields · pool (sync.Pool) │
│ stack[][]*Route · treeStack[]map[int][]*Route │
└──────────┬──────────────────────────────────┬───────────────┘
│ builds │ serves via
▼ ▼
┌──────────────────────┐ ┌───────────────────────────┐
│ Router (router.go) │ │ fasthttp.Server │
│ Register routes │ │ (listen.go / prefork.go) │
│ Build prefix tree │ └───────────┬───────────────┘
│ app.next() dispatch │ │ per-request
└──────────────────────┘ ▼
┌───────────────────────────────┐
│ DefaultCtx (ctx.go) │
│ Wraps fasthttp.RequestCtx │
│ Request/Response API │
│ Binder · Redirect · Locals │
└───────────┬───────────────────┘
│ passed to
▼
┌───────────────────────────────┐
│ Handler Chain │
│ middleware[0] → middleware[1] │
│ → ... → route handler │
└───────────────────────────────┘
Supporting subsystems:
binder/ — request body/param binding (JSON, XML, CBOR, form, query, etc.)
client/ — built-in HTTP client sharing serialization infrastructure
middleware/* — 30 production middleware packages (each self-contained)
log/ — logging interface + default adapter
internal/ — memory cache, storage interface wrapper (used by middleware)
addon/retry/ — retry wrapper for handlersCore components#
App#
- Package:
github.com/gofiber/fiber/v3(app.go) - Responsibility: Central registry and runtime. Owns the route stack, fasthttp server, context pool, hooks, state, and mount/sub-app composition. Implements the
Routerinterface for top-level route registration. - Key types:
App,Config,ErrorHandler,Handler - Dependencies: fasthttp server,
Hooks,State,mountFields,sync.PoolforDefaultCtx
Router / Route matching#
- Package:
github.com/gofiber/fiber/v3(router.go) - Responsibility: Defines the
Routerinterface,Routestruct, and the core dispatch loop (app.next,app.nextCustom). Builds a 3-char prefix hash tree (treeStack) for fast route lookup. Handles middleware ordering, route registration/removal, and auto-HEAD generation. - Key types:
Router(interface),Route,routeParser - Dependencies:
App, fasthttp utils for unsafe string operations
DefaultCtx / Ctx interface#
- Package:
github.com/gofiber/fiber/v3(ctx.go,ctx_interface_gen.go) - Responsibility: Wraps a
fasthttp.RequestCtxand exposes Fiber’s request/response API. Implementscontext.Contextandio.Writer. Holds route index, matched params, flash messages, and theBind/Redirecthelpers. Its interface (Ctx) is generated byifacemakerfrom theDefaultCtxstruct to ensure the interface stays in sync with the implementation. - Key types:
DefaultCtx,Ctx(generated interface),CustomCtx(extension interface) - Dependencies: fasthttp,
binder.Bind,Redirect
Binder subsystem#
- Package:
github.com/gofiber/fiber/v3/binder - Responsibility: Decoupled request-data binding for all content types (JSON, XML, CBOR, form, multipart, query string, header, cookie, URI params, msgpack). Each binder is a small struct implementing a shared interface. Exposed to users via
ctx.Bind(). - Key types:
Bindinginterface, concrete binders per content type - Dependencies: encoding packages only; does not import the root
fiberpackage (unidirectional dependency)
Hooks / lifecycle events#
- Package:
github.com/gofiber/fiber/v3(hooks.go) - Responsibility: Provides an observable lifecycle:
OnRoute,OnName,OnGroup,OnListen,OnPreStartup,OnPostStartup,OnPreShutdown,OnPostShutdown,OnFork,OnMount. Each hook slot is a slice of typed function callbacks registered by user code. - Key types:
Hooks, 11 handler type aliases - Dependencies:
App,log/
Services / managed lifecycle#
- Package:
github.com/gofiber/fiber/v3(services.go) - Responsibility: Provides a
Serviceinterface (Start/State/Terminate/String) for wiring long-running dependencies (databases, caches, etc.) into the app lifecycle. Services are started before the server begins accepting requests and terminated on graceful shutdown. Their runtime state is tracked inApp.state. - Key types:
Service(interface) - Dependencies:
State,context
State#
- Package:
github.com/gofiber/fiber/v3(state.go) - Responsibility: App-level key/value store for arbitrary shared data across handlers. Also tracks which
Serviceinstances have been started. Provides a type-safeSet[T]/Get[T]generic API. - Key types:
State - Dependencies: none beyond stdlib
Listen / prefork#
- Package:
github.com/gofiber/fiber/v3(listen.go,prefork.go) - Responsibility: Creates and configures the
fasthttp.Server, binds to TCP/Unix sockets, handles TLS (including Let’s Encrypt autocert and mTLS), prints the startup banner, triggers lifecycle hooks, and manages graceful shutdown. The prefork path spawns child processes usingSO_REUSEPORTto saturate multiple CPU cores. - Key types:
ListenConfig - Dependencies:
fasthttp.Server,autocert,tls, lifecycle hooks
Middleware packages (30+)#
- Package:
github.com/gofiber/fiber/v3/middleware/* - Responsibility: Self-contained HTTP middleware packages — each exposes a
New(config ...Config) fiber.Handlerfactory. They depend on the rootfiberpackage forCtx,Handler,App, andStoragetypes but are never imported by the core. - Key types: per-package
Config+New()function; some useinternal/storagefor pluggable backends.
HTTP Client#
- Package:
github.com/gofiber/fiber/v3/client - Responsibility: A full HTTP client (request builder, response, cookie jar, transport, lifecycle hooks) that shares serialization codecs with the server. Not required for server usage; provides a symmetric API experience.
- Key types:
Client,Request,Response - Dependencies: fasthttp for HTTP transport
Data flow#
Typical HTTP request lifecycle:
1. net.Listener accepts TCP connection → fasthttp.Server reads request bytes
2. fasthttp.Server calls app.requestHandler(rctx *fasthttp.RequestCtx)
3. app.requestHandler:
a. acquires DefaultCtx from sync.Pool (zero-allocation hot path)
b. wraps rctx in DefaultCtx (or CustomCtx if configured)
c. checks for flash cookies (redirects with messages)
d. calls app.next(ctx) to walk the route/middleware stack
4. app.next (router.go:115):
a. looks up the per-method route bucket from treeStack using
a 3-char prefix hash of the path
b. iterates routes in registration order:
- calls route.match() for path + param extraction
- if matched: executes route.Handlers[0](ctx), returns
c. handler calls ctx.Next() → app.next() continues down the chain
d. last handler returns nil → control unwinds up the chain
5. Any non-nil error propagates to app.config.ErrorHandler(ctx, err)
6. DefaultCtx released back to sync.Pool via defer app.ReleaseCtx(ctx)Concrete example — authenticated JSON API:
Request →
[1] recover middleware (catches panics)
[2] cors middleware (sets CORS headers)
[3] keyauth middleware (validates Bearer token via validator func)
[4] requestid middleware (attaches X-Request-ID)
[5] route handler (reads JSON body via ctx.Bind().JSON(&dto), calls service, returns ctx.JSON(result))
← ResponseInitialization / Bootstrap#
fiber.New(config ...Config) // app.go:543
├── allocate App struct
├── create sync.Pool { New: NewDefaultCtx }
├── newHooks(app) // hooks.go
├── newMountFields(app) // mount.go
├── newState() // state.go
├── apply config defaults (body limit, codecs, colors, methods)
├── build app.stack[][]*Route (per HTTP method)
├── build app.treeStack[]map[int][]*Route
└── app.init() — registers internal server-sent events handler if needed
app.Use(mw...) / app.Get(path, handler) // router.go:register
└── appends *Route to app.stack[method]
sets routesRefreshed = true
app.Listen(addr, ListenConfig{}) // listen.go:172
├── configure TLS / autocert
├── BeforeServeFunc hook (if set)
├── app.startupProcess():
│ ├── app.buildTree() // constructs treeStack from stack
│ ├── app.ensureAutoHeadRoutes()
│ ├── app.initServices() // starts Service instances
│ ├── execute OnListen hooks
│ └── print startup banner
├── net.Listen(network, addr)
├── fasthttp.Server.Serve(listener) // blocking
└── on SIGINT/SIGTERM or GracefulContext cancel:
app.hooks OnPreShutdown
fasthttp.Server.ShutdownWithContext
app.shutdownServices()
app.hooks OnPostShutdownDependency injection: Manual only. There is no Wire/Dig/Fx. Users wire dependencies through closures passed as handlers, or by storing shared objects in app.state / app.config.Services. The Service interface is a lightweight lifecycle pattern, not a DI container.
Configuration#
Configuration is a single flat struct (fiber.Config) passed to fiber.New(). There is no Viper, no env binding, no file parsing — Fiber is a library, so it delegates config loading to the user. Key configuration surface:
- Serialization codecs:
JSONEncoder/JSONDecoder,MsgPackEncoder/MsgPackDecoder,CBOREncoder/CBORDecoder,XMLEncoder/XMLDecoder— all swappable via function fields, enabling sonic/jsoniter/etc. - Template engine:
Viewsinterface — pluggable renderer (html/template, pug, jet, etc.) - Router behavior:
StrictRouting,CaseSensitive,UnescapePath,DisableHeadAutoRegister - Error handler:
ErrorHandler— global error centralization point - Server limits:
BodyLimit,Concurrency,ReadTimeout,WriteTimeout - Services:
Services []Service— lifecycle-managed dependencies - TLS is configured at listen time via
ListenConfig, notConfig, keeping the app struct decoupled from transport concerns.
Key design decisions#
fasthttp as the HTTP engine. Fiber was purpose-built on fasthttp for zero-allocation request handling. The
sync.Pool-backedDefaultCtx,UnsafeString/UnsafeBytesconversions, and the 3-char prefix routing tree all serve this goal. The tradeoff is thatnet/httpcompatibility requires themiddleware/adaptorbridge package.Generated
Ctxinterface viaifacemaker. Rather than hand-writing the 100+ methodCtxinterface, Fiber generates it fromDefaultCtxannotations. This keeps interface and implementation in sync automatically and enables mock implementations for testing without manual upkeep. It is an unconventional choice that pragmatically solves a real maintenance problem.Monorepo middleware distribution. All 30+ middleware packages live in the same module, versioned together. This eliminates “middleware version mismatch” bugs at the cost of a larger repo. Middleware can rely on unexported types in
internal/and get first-class CI coverage.Dual dispatch path:
DefaultCtxvsCustomCtx. The router has two code paths — a fast path for the common case (*DefaultCtxtype assertion inrequestHandler) and a general path for user-defined context types (nextCustom). This avoids interface overhead on the hot path while still supporting extensibility.Serviceinterface for managed lifecycle. Rather than requiring users to wire shutdown hooks manually, theServices []Serviceconfig field provides a structured start/stop lifecycle with state tracking. This bridges the gap between “framework” and “application server” use cases without imposing a full DI framework.