zip

package module
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2026 License: MIT Imports: 20 Imported by: 0

README

zip

Hanzo's canonical Go web framework. Built on Fiber v3 / fasthttp. Sinatra-style API. ZAP-typed handlers. Multi-language extension support via HIP-0105.

ONE framework. ZERO escape hatches. zip IS fast.

package main

import (
    "github.com/hanzoai/zip"
    "github.com/hanzoai/zip/middleware"
)

func main() {
    app := zip.New(zip.Config{})
    app.Use(middleware.Recover(), middleware.RequestID())

    app.Get("/health", func(c *zip.Ctx) error {
        return c.JSON(200, map[string]string{"status": "ok"})
    })

    v1 := app.Group("/v1")
    v1.Get("/users/:id", func(c *zip.Ctx) error {
        return c.JSON(200, map[string]string{
            "id":  c.Param("id"),
            "org": c.Org(),       // HIP-0026 gateway-minted X-Org-Id
            "user": c.User(),     // X-User-Id
        })
    })

    _ = app.Listen(":9653", "http://:8080") // ZAP primary + HTTP extra, one verb
}

Features

  • Sinatra/Express idiomapp.Get(path, fn) is the primary API.
  • Typed handlerszip.Get[In, Out](app, path, fn) generates OpenAPI 3.1 spec and serves Swagger UI at /docs.
  • Hanzo identity built-inc.Org() / c.User() / c.UserEmail() pull JWT-validated values from gateway X-* headers per HIP-0026.
  • luxfi/log for all logging — no slog or zap in zip.
  • Extension routesapp.Module("POST /v1/eval", "wasm", "./policy") mounts any HIP-0105 extension as a route. Supports wasm (wazero) / goja / pyvm / starlark / v8go / native.
  • Embedded JS runtimeruntime.NewJSRuntime runs TS/JS handlers in-process via goja (pure Go, no CGO). runtime.TranspileToES5 compiles TS → goja-ready JS via esbuild. runtime.JSHandler / runtime.JSModule mount an Express-shaped JS function as a route.
  • WebSocketwsx.Upgrade(fn) via fasthttp/websocket.
  • SSE / streamingc.SendStreamWriter (Fiber v3 native).
  • Drop-in migrationapp.Mount("/legacy", chiRouter) for any http.Handler (chi, gin, beego, net/http).
  • Free MCP — every typed handler (zip.Get/Post[In,Out]) is automatically a Model Context Protocol tool at /mcp (JSON-RPC 2.0): tools/list projects the same JSON Schema OpenAPI uses, tools/call runs the exact same fn. ONE op registry → three projections (REST route · OpenAPI doc · MCP tool). Because /mcp is an ordinary route, it's served over every transport you Listen on, so ZAP-native MCP is automatic — an agent speaking ZAP gets the tool surface with zero wiring. On by default; Config.MCP.Disabled to suppress.
  • Transport is a value, not a method — ONE verb, app.Listen(addrs...), and the address scheme selects the transport (mirrors net.Listen(network, addr)):
    app.Listen(":9653")                   // ZAP (bare addr = the primary)
    app.Listen(":9653", "http://:8080")   // ZAP + HTTP in one call
    app.Listen("http://:8080")            // HTTP only
    app.Listen("quic://:443")             // any RegisterTransport'd protocol
    
    ZAP (TLS 1.3 + post-quantum, gRPC's replacement) is the default; HTTP is built in; zip.RegisterTransport(scheme, fn) slots in any future termination/ serialization protocol with ZERO change to the Listen API. Your routes ARE the surface — same handlers, middleware, and auth over every transport.
  • Named-service RPC (optional)zaprpc.Registry + zaprpc.HTTPHandler(reg) exposes generated zapc services by name at a route, for a gRPC-style service surface on top of the transport.

Install

go get github.com/hanzoai/zip

Module path: github.com/hanzoai/zip. Go version: 1.26.3 (forced by luxfi/log).

JSON: encoding/json/v2 at the edge

zip routes every JSON path — c.JSON, c.Bind().Body, the typed zip.Get[In,Out] round-trip, the HIP-0105 module envelope, the auto-OpenAPI spec — through one internal helper (internal/jsonenc). When the binary is compiled with GOEXPERIMENT=jsonv2 (Go 1.25+), that helper is backed by the stdlib encoding/json/v2; otherwise it falls back to encoding/json v1. There is no third-party JSON library: stdlib only, per HIP-0106's canonical Hanzo Go stack.

# Compile with v2 (preferred — ~10% faster on the edge,
# ~25% fewer allocations per request)
GOEXPERIMENT=jsonv2 go build ./...

# Without the experiment, v1 is selected:
go build ./...

zip.JSONVariant is a build-time constant exposing which impl is active. zip.New logs it once at startup so operators can confirm v2 is on in CI/prod logs:

{"level":"info","module":"zip","json_variant":"encoding/json/v2","message":"zip new"}

Benchmarks (Apple M1 Max, Go 1.26, fiber/v3):

Bench json v1 ns/op json/v2 ns/op v1 allocs v2 allocs Δ
Edge POST + JSON roundtrip 14972 13631 73 56 -9% time, -23% allocs
Marshal-only 10798 7924 34 34 -27% time
Unmarshal-only 13803 12729 67 50 -8% time, -25% allocs

Reproduce with go test -bench=BenchmarkJSON -benchmem ./... and again with GOEXPERIMENT=jsonv2.

Per HIP-0106 "Wire protocol stack": JSON marshalling happens at most ONCE per request (at the subsystem handler boundary, through zip). Inter-subsystem calls use ZAP-typed Go values via cloud.Deps. JSON is the edge format only.

Embedded JS runtime — the TS migration path

zip embeds a JavaScript runtime so legacy TS/JS handlers run in the same Go process — no separate hanzo/runtime service, no inter-service RPC, no container-per-service. Combined with the single-binary architecture below, this is where the cloud savings come from: one process mounts everything.

TS source  --esbuild target=ES2015-->  ES JS  --drop into-->  embedded goja  --in-process-->  Fiber route
// 1. Transpile legacy TS to goja-runnable JS (pure Go, no CGO).
js, _ := runtime.TranspileToES5(tsSource, runtime.ESOptions{Loader: "ts"})

// 2. Pool-backed embedded VM; register the CommonJS module.
rt, _ := runtime.NewJSRuntime(runtime.JSOptions{PoolSize: 8})
_ = rt.LoadModule("app", string(js)) // module.exports = (req, res) => ...

// 3. Express-shaped handler -> fiber.Handler, mounted on zip.
h, _ := runtime.JSModule(rt, "app")
app.Fiber().All("/legacy/*", h)

The JS handler sees an Express-shaped (req, res) pair — req.method / req.path / req.query / req.headers / req.body and res.status(n) / res.set(k,v) / res.json(v) / res.send(v). JSON encode/decode routes through the same internal/jsonenc impl as the edge, so there is one wire format.

Migrate in place, incrementally: start with the TS handler running in goja (zero rewrite), then rewrite hot routes to native Go func(c *zip.Ctx) error one at a time. Both styles coexist on the same App.

esbuild's pure-Go API emits ES2015 as its lowest target (it does not emit literal ES5); goja runs ES2015 output. TranspileToES5 is named for the migration intent — "down to what the embedded VM runs."

A pool of *goja.Runtime (lifted from hanzoai/base/plugins/gojavm) keeps VMs hot so requests don't pay per-request VM-creation cost; goja VMs are single-threaded, so each request borrows an isolated VM.

See examples/express-in-zip/ for the full esbuild → goja → Fiber proof point with an integration test.

Single-binary architecture (HIP-0106)

zip is the seam that lets hanzoai/cloud mount every Hanzo subsystem into ONE Go process. Each subsystem exposes Mount(app *zip.App, deps) (see examples/subsystem-mount); cloud builds the dependency bag once and threads it through every mount. Native Go subsystems, embedded-JS legacy handlers, WebSocket endpoints, and the ZAP RPC plane all run on the same App. No microservice overhead, no inter-service RPC, no container-per-service — JSON only at the edge, ZAP-typed Go values between subsystems.

Architecture

  • zip.App wraps *fiber.App. One binary, one server, no escape hatches — no .Fast variant API, no second router.
  • zip.Ctx wraps fiber.Ctx and adds Hanzo identity sugar (c.Org() / c.User() / c.IsAdmin() / c.RequestID() / c.Log()).
  • Handlers are func(c *zip.Ctx) error. Returning a *zip.HTTPError controls the response status; everything else becomes 500 JSON.
  • Middleware lives in zip/middleware/Recover, Logger, RequestID, RateLimit, CORS, MaxBody, Telemetry. Auth- specific middleware (Auth, StripIdentityHeaders) lives in github.com/hanzoai/gateway/middleware per HIP-0106.
  • Adapters in zip/adapt.goAdaptNetHTTP / AdaptNetHTTPFunc / AdaptNetHTTPMiddleware. Migration tools only — replace adapted routes with native handlers when feasible.
  • Extension runtime contract in zip/runtime/ — duck-typed runtime.Loader interface; zip does NOT pull hanzoai/base as a dep. Service binaries construct *extruntime.Loader and inject via zip.Config.Loader.

Examples

Example Demonstrates
examples/hello Minimal Sinatra-style API
examples/zap-typed Generic typed handler + auto-OpenAPI
examples/express-in-zip Legacy TS handler: esbuild → goja → Fiber
examples/subsystem-mount HIP-0106 Mount(*App, deps) idiom
examples/module-routes app.Module() over a runtime.Loader
examples/websocket wsx.Upgrade echo server
examples/sse-streaming Server-Sent Events via SendStreamWriter
examples/migrate-from-gin gin→zip mechanical port
examples/migrate-from-chi chi→zip via AdaptNetHTTP
examples/migrate-from-beego beego→zip via AdaptNetHTTP

Migration

From Adapter
net/http zip.AdaptNetHTTP(httpHandler)
chi zip.AdaptNetHTTP(chiRouter) (chi.Router IS http.Handler)
gin zip.AdaptNetHTTP(ginEngine) (gin.Engine IS http.Handler)
beego app.Mount("/legacy/iam", beeApp.Handlers)

Each adapter is doc'd "MIGRATION TOOL — costs ~5% perf vs native Fiber dispatch. Replace with native handlers when feasible."

See docs/MIGRATION.md for per-framework recipes.

License

Apache-2.0 (carry-forward from upstream zeekay/zip license metadata).

Documentation

Overview

Package zip is Hanzo's canonical Go web framework. Built on Fiber v3 / fasthttp. Sinatra-style API. ZAP-typed handlers. Multi-language extension support via HIP-0105.

ONE framework, ZERO escape hatches. zip IS fast.

app := zip.New(zip.Config{Logger: luxlog.NewLogger("svc")})
app.Use(middleware.Recover(), middleware.RequestID())
app.Get("/health", func(c *zip.Ctx) error {
    return c.JSON(200, fiber.Map{"ok": true})
})
app.Listen(":9653", "http://:8080") // ZAP primary + HTTP extra, one verb

Public surface — types/functions exposed at the package root:

type App, Config, Ctx, Handler
func New(Config) *App
func Get[I, O](app *App, path string, fn func(ctx, *I) (*O, error))
func Post[I, O](app *App, path string, fn func(ctx, *I) (*O, error))
...

All other behavior lives in subpackages: `middleware`, `runtime`.

Index

Constants

View Source
const DefaultScheme = "zap"

DefaultScheme is the transport a bare address (no "scheme://") uses. ZAP is the primary transport (TLS 1.3 + post-quantum, gRPC's replacement), so the path of least resistance is ZAP-native.

View Source
const JSONVariant = jsonenc.Variant

JSONVariant reports which JSON implementation zip is using in this build — "encoding/json/v2" when compiled with GOEXPERIMENT=jsonv2, "encoding/json" otherwise. Exposed for cmd/cloud startup logs and for tests that need to assert the variant. Per HIP-0106 the wire stack is "JSON only at edge, ZAP between services"; this constant tells operators which JSON impl is on the edge.

Variables

This section is empty.

Functions

func Delete

func Delete[In, Out any](app *App, path string, fn TypedHandler[In, Out], opts ...OpOption)

Delete registers a DELETE typed handler at path.

func Get

func Get[In, Out any](app *App, path string, fn TypedHandler[In, Out], opts ...OpOption)

Get registers a GET typed handler at path.

func Patch

func Patch[In, Out any](app *App, path string, fn TypedHandler[In, Out], opts ...OpOption)

Patch registers a PATCH typed handler at path.

func Post

func Post[In, Out any](app *App, path string, fn TypedHandler[In, Out], opts ...OpOption)

Post registers a POST typed handler at path.

func Put

func Put[In, Out any](app *App, path string, fn TypedHandler[In, Out], opts ...OpOption)

Put registers a PUT typed handler at path.

func RegisterTransport added in v1.1.0

func RegisterTransport(scheme string, tf TransportFunc)

RegisterTransport adds (or replaces) a transport keyed by address scheme, so any future termination/serialization protocol slots in with ZERO change to the Listen API. Call before Listen.

zip.RegisterTransport("quic", func(addr string, h fasthttp.RequestHandler) zip.Server {
	return myquic.NewServer(addr, h)
})

Types

type App

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

App is the zip application. It wraps *fiber.App and exposes the zip handler signature alongside generic typed handlers.

func New

func New(cfg Config) *App

New constructs an App with the given config. Defaults are applied for any zero-valued field.

func (*App) All

func (a *App) All(path string, h Handler) Router

All registers a handler for any HTTP method.

func (*App) Delete

func (a *App) Delete(path string, h Handler) Router

func (*App) Fiber

func (a *App) Fiber() *fiber.App

Fiber returns the underlying *fiber.App. Use for one-off escape into Fiber-only APIs (rare). Prefer staying on the zip surface.

func (*App) Get

func (a *App) Get(path string, h Handler) Router

Get / Post / Put / Patch / Delete / Head / Options / All / Add register routes.

func (*App) Group

func (a *App) Group(prefix string, handlers ...Handler) Router

Group creates a path-prefixed router group.

func (*App) Head

func (a *App) Head(path string, h Handler) Router

func (*App) Listen added in v1.1.0

func (a *App) Listen(addrs ...string) error

Listen serves the app on one or more addresses and blocks until all listeners stop or the first one errors. The address scheme selects the transport; a bare address uses ZAP (DefaultScheme). This is the ONE and only way to serve a zip app — no per-transport methods.

func (*App) Logger

func (a *App) Logger() luxlog.Logger

Logger returns the App's logger.

func (*App) Module

func (a *App) Module(methodPath, runtimeName, modulePath string) error

Module mounts a single HIP-0105 extension at the given method+path. The `methodPath` form is "METHOD /path" (e.g. "POST /v1/validate"), matching the Sinatra/Express idiom. `runtime` selects the backing engine ("wasm" | "goja" | "pyvm" | "starlark" | "v8go" | "native"); `modulePath` is the directory containing the extension.json manifest.

app.Module("POST /v1/policy/eval", "wasm", "./extensions/policy")
app.Module("POST /v1/transform",   "pyvm", "./extensions/transform")
app.Module("POST /v1/webhook",     "goja", "./extensions/webhook")

The extension's exported function name is inferred from the path's last segment unless explicitly overridden via app.ModuleFn().

func (*App) ModuleFn

func (a *App) ModuleFn(method, path, fn, runtimeName, modulePath string) error

ModuleFn is the explicit form of Module — caller specifies the guest's exported function name directly.

func (*App) Mount

func (a *App) Mount(prefix string, h http.Handler)

Mount registers an http.Handler at the given prefix. Implicit chi.Router and gin.Engine support flows through AdaptNetHTTP via their respective ServeHTTP methods — both are http.Handlers.

app.Mount("/legacy/chi",  zip.AdaptNetHTTP(chiRouter))
app.Mount("/legacy/gin",  zip.AdaptNetHTTP(ginEngine))
app.Mount("/legacy/iam",  zip.AdaptNetHTTP(beegoApp.HandlerWrapper()))

Migration tool — costs ~5% perf vs native Fiber.

func (*App) Options

func (a *App) Options(path string, h Handler) Router

func (*App) Patch

func (a *App) Patch(path string, h Handler) Router

func (*App) Post

func (a *App) Post(path string, h Handler) Router

func (*App) Put

func (a *App) Put(path string, h Handler) Router

func (*App) Route

func (a *App) Route(prefix string, fn func(r Router)) Router

Route runs fn against a path-prefixed router group.

func (*App) Shutdown

func (a *App) Shutdown() error

Shutdown gracefully stops both transports.

func (*App) ShutdownWithContext

func (a *App) ShutdownWithContext(ctx context.Context) error

ShutdownWithContext gracefully stops both transports bounded by ctx.

func (*App) Use

func (a *App) Use(handlers ...Handler) Router

Use registers zip-style middleware. Each Handler runs in order; calling c.Next() (via c.Continue) chains to the next handler.

func (*App) UseFiber

func (a *App) UseFiber(handlers ...fiber.Handler) Router

UseFiber lets callers register raw fiber.Handler middleware (for the fiber/v3/middleware/* packages). zip middleware is preferred.

type Config

type Config struct {
	// Logger is the luxfi/log Logger zip uses internally. Required.
	// If nil, a default one is created via luxlog.NewLogger("zip").
	Logger luxlog.Logger

	// Loader is the HIP-0105 extension runtime loader. nil disables
	// app.Module() — only native handlers will work. The interface is
	// satisfied by *extruntime.Loader from hanzoai/base/plugins/extruntime;
	// zip does NOT take a hard dep on hanzoai/base.
	Loader runtime.Loader

	// AllowedRuntimes restricts which extension runtimes app.Module()
	// will accept (e.g. ["goja","wazero"] for hard multi-tenant safety).
	// nil = allow whatever the Loader has registered.
	AllowedRuntimes []string

	// ServerHeader is sent as the Server: response header (default "zip").
	// Set to "-" to suppress.
	ServerHeader string

	// BodyLimit is the maximum request body size (default 4 MiB).
	BodyLimit int

	// AppName forwards to fiber.Config.AppName.
	AppName string

	// DisableStartupMessage suppresses Fiber's startup banner.
	DisableStartupMessage bool

	// ErrorHandler is the catch-all error handler. Defaults to zip.errorHandler
	// which renders {error, code, status} JSON.
	ErrorHandler fiber.ErrorHandler

	// Concurrency caps the maximum number of concurrent connections the
	// server will accept. Default 0 means fasthttp's own default
	// (256*1024). Ops should cap this at the per-replica budget — see
	// `~/work/hanzo/hips/docs/SCALE_STANDARD.md`. With Hanzo's verified
	// 8 KiB/conn budget, 100_000 sits at ~800 MiB inside a 1 GiB pod.
	Concurrency int

	// ReadBufferSize is fasthttp's per-conn request-read buffer (default
	// 4 KiB). Raise only for header-heavy upstreams; raising it inflates
	// the per-conn memory budget and breaks the conn-memory regression
	// gate (see SCALE_STANDARD.md §8).
	ReadBufferSize int

	// WriteBufferSize is fasthttp's per-conn response-write buffer
	// (default 4 KiB). Raise only for streaming-heavy responses; same
	// budget caveat as ReadBufferSize.
	WriteBufferSize int

	// OpenAPI configures the auto-generated /.well-known/openapi.json
	// served when typed handlers are registered.
	OpenAPI OpenAPIConfig

	// MCP configures the Model Context Protocol tool surface auto-derived from
	// typed handlers (Get/Post[In,Out]). Enabled by default — it's free (the
	// same op registry that feeds OpenAPI), served over every transport. Set
	// MCP.Disabled to suppress.
	MCP MCPConfig
}

Config configures the zip App. Most fields pass through to Fiber's own Config; a few zip-specific knobs control runtime loading.

type Ctx

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

Ctx wraps fiber.Ctx and adds the Hanzo identity surface (Org/User/Email from gateway-minted X-* headers per HIP-0026), a per-request luxfi/log logger, and typed Deps access.

func (*Ctx) App

func (c *Ctx) App() *App

App returns the parent App.

func (*Ctx) Bind

func (c *Ctx) Bind(v any) error

Bind parses the request body into v based on Content-Type (JSON by default) and runs struct-tag validation (required/min/max/minlen/maxlen). Returns a *HTTPError(400) when either step fails so handlers can return the error directly.

func (*Ctx) BindQuery

func (c *Ctx) BindQuery(v any) error

BindQuery parses query parameters into v and runs validation.

func (*Ctx) BindURI

func (c *Ctx) BindURI(v any) error

BindURI parses URL params into v and runs validation.

func (*Ctx) Body

func (c *Ctx) Body() []byte

Body returns the raw request body.

func (*Ctx) Bytes

func (c *Ctx) Bytes(code int, b []byte) error

Bytes writes raw bytes.

func (*Ctx) Context

func (c *Ctx) Context() context.Context

Context returns the standard context.Context (deadline + cancellation).

func (*Ctx) Continue

func (c *Ctx) Continue() error

Continue is an alias for Next() with the standard middleware idiom.

func (*Ctx) Fiber

func (c *Ctx) Fiber() fiber.Ctx

Fiber returns the underlying fiber.Ctx for one-off escape into Fiber-only APIs.

func (*Ctx) Header

func (c *Ctx) Header(name string) string

Header returns a request header.

func (*Ctx) IsAdmin

func (c *Ctx) IsAdmin() bool

IsAdmin returns the X-User-IsAdmin gateway claim as a bool.

func (*Ctx) JSON

func (c *Ctx) JSON(code int, v any) error

JSON writes the value as JSON with status code.

func (*Ctx) Locals

func (c *Ctx) Locals(key any, value ...any) any

Locals returns or sets a per-request value.

func (*Ctx) Log

func (c *Ctx) Log() luxlog.Logger

Log returns the request-scoped logger. Middleware that adds request_id, org, user, etc. via Locals can enrich this by calling SetLog.

func (*Ctx) Method

func (c *Ctx) Method() string

Method returns the request method.

func (*Ctx) Next

func (c *Ctx) Next() error

Next yields to the next handler in the chain. Use sparingly from zip middleware — middleware bodies usually call c.Continue() at the end, not Next() mid-handler.

func (*Ctx) NoContent

func (c *Ctx) NoContent(code int) error

NoContent writes the status code with no body.

func (*Ctx) Org

func (c *Ctx) Org() string

Org returns the X-Org-Id from the JWT-validated gateway. Empty when no gateway is in front (local dev / direct ingress).

func (*Ctx) Param

func (c *Ctx) Param(name string) string

Param returns a URL path parameter.

func (*Ctx) Path

func (c *Ctx) Path() string

Path returns the request path.

func (*Ctx) Query

func (c *Ctx) Query(name string) string

Query returns a URL query parameter.

func (*Ctx) RequestID

func (c *Ctx) RequestID() string

RequestID returns the value of X-Request-Id (set by the RequestID middleware).

func (*Ctx) SendStream

func (c *Ctx) SendStream(r io.Reader) error

SendStream streams data from r to the client (e.g. for SSE).

func (*Ctx) SendStreamWriter

func (c *Ctx) SendStreamWriter(fn func(w *bufio.Writer)) error

SendStreamWriter writes streaming output via a bufio.Writer (Server-Sent Events / chunked transfer). Forwards to fiber.Ctx.SendStreamWriter.

func (*Ctx) SetHeader

func (c *Ctx) SetHeader(name, value string)

SetHeader sets a response header.

func (*Ctx) SetLog

func (c *Ctx) SetLog(l luxlog.Logger)

SetLog replaces the request logger (typically by middleware that wants to attach request-id / org / user fields).

func (*Ctx) Status

func (c *Ctx) Status(code int) *Ctx

Status sets the response status. Chains.

func (*Ctx) String

func (c *Ctx) String(code int, s string) error

String writes a plain-text response.

func (*Ctx) User

func (c *Ctx) User() string

User returns the X-User-Id from the JWT-validated gateway.

func (*Ctx) UserEmail

func (c *Ctx) UserEmail() string

UserEmail returns the X-User-Email from the JWT-validated gateway.

type HTTPError

type HTTPError struct {
	Status int    `json:"status"`
	Code   string `json:"code,omitempty"`
	Msg    string `json:"error"`
}

HTTPError is the canonical error type zip understands. Returning one causes the error handler to send a JSON {error, code, status} body.

func ErrBadRequest

func ErrBadRequest(msg string) *HTTPError

Common shortcuts.

func ErrConflict

func ErrConflict(msg string) *HTTPError

func ErrForbidden

func ErrForbidden(msg string) *HTTPError

func ErrInternal

func ErrInternal(msg string) *HTTPError

func ErrNotFound

func ErrNotFound(msg string) *HTTPError

func ErrUnauthorized

func ErrUnauthorized(msg string) *HTTPError

func Errorf

func Errorf(status int, format string, args ...any) *HTTPError

Errorf builds an HTTPError with the given status and message.

func (*HTTPError) Error

func (e *HTTPError) Error() string

type Handler

type Handler func(c *Ctx) error

Handler is zip's request handler signature. Returning an error causes Fiber's error chain to write a JSON response.

func AdaptNetHTTP

func AdaptNetHTTP(h http.Handler) Handler

AdaptNetHTTP wraps an http.Handler so it can be mounted on a zip router. Use for stdlib code:

app.Mount("/legacy/net", zip.AdaptNetHTTP(httpHandler))

Migration tool — costs ~5% perf vs native Fiber. Replace with native zip handlers when feasible.

func AdaptNetHTTPFunc

func AdaptNetHTTPFunc(h http.HandlerFunc) Handler

AdaptNetHTTPFunc wraps an http.HandlerFunc.

Migration tool — costs ~5% perf vs native Fiber.

func AdaptNetHTTPMiddleware

func AdaptNetHTTPMiddleware(mw func(http.Handler) http.Handler) Handler

AdaptNetHTTPMiddleware wraps a stdlib middleware (func(http.Handler) http.Handler).

Migration tool — costs ~5% perf vs native Fiber.

type MCPConfig added in v1.1.0

type MCPConfig struct {
	// Disabled suppresses the /mcp route (MCP is on by default — it's free).
	Disabled bool
	// Path overrides the mount path (default "/mcp").
	Path string
	// Name is the server name reported to MCP clients (default AppName, else "zip").
	Name string
}

MCPConfig configures the auto-derived MCP surface.

type OpOption

type OpOption func(*registeredOp)

OpOption configures a typed handler registration (OpenAPI metadata).

func WithOperationID

func WithOperationID(id string) OpOption

WithOperationID sets the operation ID in OpenAPI.

func WithSummary

func WithSummary(s string) OpOption

WithSummary sets the operation summary in OpenAPI.

func WithTags

func WithTags(tags ...string) OpOption

WithTags sets the operation tags in OpenAPI.

type OpenAPIConfig

type OpenAPIConfig struct {
	// Title appears in the OpenAPI info block.
	Title string
	// Description appears in the OpenAPI info block.
	Description string
	// Version appears in the OpenAPI info block (e.g. "v1.0.0").
	Version string
	// Disabled suppresses the /.well-known/openapi.json route and /docs.
	Disabled bool
}

OpenAPIConfig configures the auto-generated /.well-known/openapi.json endpoint zip serves when typed handlers are registered.

type Router

type Router interface {
	Use(handlers ...Handler) Router

	Get(path string, h Handler) Router
	Post(path string, h Handler) Router
	Put(path string, h Handler) Router
	Patch(path string, h Handler) Router
	Delete(path string, h Handler) Router
	Head(path string, h Handler) Router
	Options(path string, h Handler) Router
	All(path string, h Handler) Router

	Group(prefix string, handlers ...Handler) Router
	Route(prefix string, fn func(r Router)) Router

	// Fiber returns the underlying fiber.Router for one-off escape.
	Fiber() fiber.Router
}

Router is the path-mounting surface shared by *App and Group. All concrete routes flow through toFiberHandler — fiber.Ctx is the underlying type the framework's users never see directly.

type Server added in v1.1.0

type Server interface {
	ListenAndServe() error
	Close() error
}

Server is a running transport listener bound to one address. Both zap-proto/http.Server and the built-in HTTP server satisfy it, as does any custom transport.

type TransportFunc added in v1.1.0

type TransportFunc func(addr string, handler fasthttp.RequestHandler) Server

TransportFunc builds a Server that serves handler on addr. Register one per address scheme with RegisterTransport — that is the ONLY extension point; the Listen API never changes as protocols are added.

type TypedHandler

type TypedHandler[In, Out any] func(ctx context.Context, in *In) (*Out, error)

TypedHandler is the generic handler signature: takes an *In, returns (*Out, error). zip generates OpenAPI 3.1 spec from the In/Out types and registers a Fiber route that unmarshals body → In, runs the handler, and marshals Out → JSON response.

Directories

Path Synopsis
examples
express-in-zip command
express-in-zip — the proof point: a legacy Express-shaped TypeScript handler running inside zip with ZERO rewrite.
express-in-zip — the proof point: a legacy Express-shaped TypeScript handler running inside zip with ZERO rewrite.
hello command
Hello, zip — minimal example.
Hello, zip — minimal example.
migrate-from-beego command
migrate-from-beego example — beego → zip migration via http.Handler adapter.
migrate-from-beego example — beego → zip migration via http.Handler adapter.
migrate-from-chi command
migrate-from-chi example — chi → zip via stdlib adapter.
migrate-from-chi example — chi → zip via stdlib adapter.
migrate-from-gin command
migrate-from-gin example — mechanical port of a gin-style API to zip.
migrate-from-gin example — mechanical port of a gin-style API to zip.
module-routes command
module-routes example — mount HIP-0105 extension modules as routes.
module-routes example — mount HIP-0105 extension modules as routes.
sse-streaming command
sse-streaming example — Server-Sent Events via c.SendStreamWriter.
sse-streaming example — Server-Sent Events via c.SendStreamWriter.
subsystem-mount command
subsystem-mount example — HIP-0106 Mount(app, deps) idiom.
subsystem-mount example — HIP-0106 Mount(app, deps) idiom.
websocket command
websocket example — chat-style echo server.
websocket example — chat-style echo server.
zap-typed command
zap-typed example — typed handler with auto-generated OpenAPI spec.
zap-typed example — typed handler with auto-generated OpenAPI spec.
internal
jsonenc
Package jsonenc is zip's single JSON entry point.
Package jsonenc is zip's single JSON entry point.
runtime
Package runtime defines the minimal Loader / Module interface zip consumes from any HIP-0105 extension runtime implementation (hanzoai/base/plugins/extruntime is the reference).
Package runtime defines the minimal Loader / Module interface zip consumes from any HIP-0105 extension runtime implementation (hanzoai/base/plugins/extruntime is the reference).
Package middleware ships zip's canonical generic middleware stack.
Package middleware ships zip's canonical generic middleware stack.
esbuild.go wraps esbuild's pure-Go API (no CGO) so zip can compile TS / modern-JS handler source down to ES5 that the embedded goja VM executes.
esbuild.go wraps esbuild's pure-Go API (no CGO) so zip can compile TS / modern-JS handler source down to ES5 that the embedded goja VM executes.
Package wsx provides Fiber-v3-compatible WebSocket support via fasthttp/websocket.
Package wsx provides Fiber-v3-compatible WebSocket support via fasthttp/websocket.
Package zaprpc is an OPTIONAL named-service RPC dispatch helper for zip apps that want a Cap'n-Proto/gRPC-style service registry (name → method → handler) rather than plain REST routes.
Package zaprpc is an OPTIONAL named-service RPC dispatch helper for zip apps that want a Cap'n-Proto/gRPC-style service registry (name → method → handler) rather than plain REST routes.

Jump to

Keyboard shortcuts

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