fiber adapter
The fiber adapter wires jetwarp’s portable adapter.Adapter API to a driver built on top of Fiber v3.
Fiber is not net/http native (it is based on fasthttp). jetwarp still exposes standard net/http handlers,
so the Fiber driver performs a small request/response bridge at the edge.
This adapter is a good fit when you want to keep jetwarp’s portability guarantees while running on Fiber’s ecosystem.
Install
Add the adapter module to your project:
go get codeberg.org/iaconlabs/jetwarp/adapter/fiber@latest
This pulls in:
codeberg.org/iaconlabs/jetwarp(core adapter + registry)codeberg.org/iaconlabs/jetwarp/drivers/v1/fiber(Fiber v3 driver)github.com/gofiber/fiber/v3(Fiber itself)
Create a router
package main
import (
"log"
"net/http"
twfiber "codeberg.org/iaconlabs/jetwarp/adapter/fiber"
)
func main() {
r := twfiber.New()
r.HandleFunc(http.MethodGet, "/healthz", func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte("ok"))
})
// Always check accumulated registration errors before serving traffic.
if err := r.Err(); err != nil {
log.Fatal(err)
}
log.Fatal(http.ListenAndServe(":8080", r))
}
How the Fiber driver bridges net/http
jetwarp’s driver contract is net/http first: handlers are http.Handler / http.HandlerFunc.
Because Fiber is not net/http-native, the driver registers a Fiber handler wrapper that:
- reads route parameters from
fiber.Ctx - converts the Fiber request into a
*http.Request - installs path parameters into the request (see below)
- calls your
net/httphandler, using a ResponseWriter implementation that writes back to Fiber
You don’t usually need to think about this, but it explains most “Fiber-specific” behavior and limitations.
Route patterns and parameters
jetwarp’s canonical path patterns use {name} parameters (ServeMux-style):
r.HandleFunc(http.MethodGet, "/users/{id}", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
_, _ = w.Write([]byte("id=" + id))
})
Why PathValue works with Fiber
Fiber’s built-in net/http adaptor does not expose route parameters on *http.Request.
The jetwarp Fiber driver bridges parameters explicitly so both of these are true:
- driver-level access:
drv.Param(r, "id") - portable access:
r.PathValue("id")
If you ever see empty params on Fiber, treat it as a bug/regression: that invariant is pinned in tests.
Important gotcha: no in-segment suffix/prefix params
The Fiber driver is intentionally conservative about parameter correctness.
It does not support “in-segment” suffix/prefix patterns such as:
/files/{id}.json/prefix-{id}
Why? Fiber would treat :id.json as a parameter named id.json, which breaks jetwarp’s
canonical Param("id") / PathValue("id") semantics.
If you register a suffix/prefix pattern on the Fiber adapter, it should be rejected (recorded in Err())
rather than silently behaving differently.
Portable alternative: use a plain segment param and validate the suffix yourself in the handler:
- ✅
/files/{id}then checkstrings.HasSuffix(...)or parse - ❌
/files/{id}.json(not portable on Fiber)
MethodAny ("*") support
jetwarp supports method-agnostic routes via the canonical method token "*":
r.HandleFunc("*", "/any", func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte("ANY:" + r.Method))
})
On Fiber, the driver maintains two internal apps:
- primary: method-specific routes (
GET,POST, …) - any: MethodAny routes (
"*")
Request dispatch tries primary first, then falls back to any. This guarantees:
- explicit method routes win over
"*"routes for the same path "*"handles methods that do not have an explicit registration
This is enforced by regression tests and does not depend on registration order.
Middleware with Fiber
Prefer portable net/http middleware
Fiber middleware (func(*fiber.Ctx) error) is not compatible with jetwarp’s portable middleware surface.
For maximum portability, prefer standard net/http middleware wrapped with adapter.HTTP(...):
import (
"net/http"
"codeberg.org/iaconlabs/jetwarp/adapter"
)
r.Use(adapter.HTTPNamed("example", func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// before
next.ServeHTTP(w, r)
// after
})
}))
Ordering is deterministic across adapters:
Use → Group → With → per-route → handler
If you need Fiber-native middleware
If you strongly need a Fiber-native middleware or feature, you can use the engine escape hatch (see below). Be aware this steps outside the portability contract and may bypass the registry / OpenAPI tooling if you register routes directly on Fiber.
Note: jetwarp’s built-in adapters currently do not apply native middleware. If you attempt to register a non-portable middleware value, it will be recorded as
jetwarp.ErrNativeMWUnsupported.
Accessing the underlying engine (escape hatch)
Sometimes you want to interact with Fiber directly (debugging, profiling hooks, custom Fiber features).
jetwarp exposes an Engine() any escape hatch on the concrete router.
The Fiber driver’s engine value is a small struct containing the underlying apps:
Primary— method-specific appAny— MethodAny app
Example:
package main
import (
twdrv "codeberg.org/iaconlabs/jetwarp/drivers/v1/fiber"
)
type engineProvider interface {
Engine() any
}
func useEngine(r any) {
ep, ok := r.(engineProvider)
if !ok {
return
}
if eng, ok := ep.Engine().(twdrv.Engine); ok {
_ = eng.Primary // *fiber.App
_ = eng.Any // *fiber.App
}
}
If you rely on the engine in production code, consider documenting that your service is Fiber-specific.
Common pitfalls
- Forgetting
Err(): registration errors accumulate instead of panicking; always fail fast after setup. - Using
{id}.jsonpatterns: Fiber intentionally rejects these to avoid silently wrong param names. - Assuming net/http edge behavior is identical: Fiber is bridged; if you rely on advanced HTTP behaviors (streaming, websocket upgrades, connection hijacking, etc.), validate with an early spike test.
- Registering routes directly on Fiber: it can be useful, but you’ll bypass jetwarp’s registry and tooling.