zip

package module
v1.5.0 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2026 License: MIT Imports: 24 Imported by: 0

README

zip

Docs: zip · part of the ZAP Protocol

The ZAP-native Go web framework. Built on Fiber v3 / fasthttp, with a Sinatra-style API, typed handlers that project to OpenAPI and MCP, and ZAP as the primary transport — HTTP is a secondary view of the same routes.

zap-proto.io · Docs · fiber · Spec

ONE framework. ONE Listen verb. Routes defined once, served over every transport.

package main

import (
    "github.com/zap-proto/zip"
    "github.com/zap-proto/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(),  // gateway-minted X-Org-Id
            "user": c.User(), // gateway-minted X-User-Id
        })
    })

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

Install

go get github.com/zap-proto/zip

Module path github.com/zap-proto/zip. Requires Go 1.26+.

Features

  • Sinatra/Express idiomapp.Get(path, fn) is the primary API; handlers are func(c *zip.Ctx) error.

  • Transport is a value, not a method — one verb, app.Listen(addrs...), and the address scheme selects the transport (mirrors net.Listen):

    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) is the default; HTTP is built in; zip.RegisterTransport(scheme, fn) adds any future protocol with zero change to Listen.

  • One registry, three projectionszip.Get[In, Out](app, path, fn) registers one operation that becomes a REST route, an OpenAPI 3.1 doc (/.well-known/openapi.json, Swagger UI at /docs), and a Model Context Protocol tool at /mcp (JSON-RPC 2.0). Same schema, same handler. Because /mcp is an ordinary route, ZAP-native MCP is automatic. On by default; Config.MCP.Disabled to suppress.

  • Precedence is a property of the pattern — routing comes from the zap-proto/fiber fork: the most specific pattern wins regardless of registration order (static ≻ :param ≻ *), and ambiguous equal-specificity overlaps panic at startup instead of silently shadowing.

  • Identity built-inc.Org() / c.User() / c.UserEmail() / c.IsAdmin() read JWT-validated X-* headers set by the gateway; handlers never parse tokens.

  • MiddlewareRecover, RequestID, Logger, Timeout, MaxBody, CORS, RateLimit, Telemetry, Breaker in zip/middleware.

  • WebSocket & streamingwsx.Upgrade(fn) over fasthttp/websocket; c.SendStreamWriter for SSE / chunked responses.

  • Extension routesapp.Module("POST /v1/eval", "wasm", "./policy") mounts a sandboxed extension (wasm / goja / pyvm / starlark / v8go / native) as a route.

  • Embedded JS/TS runtime — run an Express-shaped JS/TS handler in-process via goja (pure Go, no CGO); esbuild transpiles TS ahead of it, for incremental migration to native Go.

  • Drop-in migrationapp.All("/legacy/*", zip.AdaptNetHTTP(h)) fronts any http.Handler (chi, gin, beego, net/http) as one wildcard route; it obeys the same precedence, so a native route added later still wins.

  • Composition by Mount — a service is a set of subsystem packages exposing func Mount(app *zip.App, deps Deps) error; a standalone binary and a fused multi-subsystem binary are the same code with a different selection.

  • Stdlib JSON only — every JSON path goes through one internal helper backed by encoding/json/v2 when built with GOEXPERIMENT=jsonv2 (Go 1.25+), else encoding/json. No third-party JSON library.

Documentation

The full guide — Ctx reference, the route-precedence contract, middleware, extension-runtime mounts, and versioning — is at zap-proto.dev/docs/zip. Runnable examples live in examples/.

License

MIT — see LICENSE.

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 deprecated

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

Mount serves an http.Handler over the subtree under prefix.

Deprecated: use app.All(prefix+"/*", zip.AdaptNetHTTP(h)) — the two primitives Mount is built from. Mount IS exactly that composition, kept as a behaviour-identical alias so existing callers keep working; preferring the explicit form leaves ONE way to put a route on the app. It also makes the mounted subtree's nature plain: it is an ordinary wildcard route, so a more specific static route wins even when registered later — app.Get(prefix+"/health", …) beats the mount by specificity, not order.

chi.Router, gin.Engine, and a beego HandlerWrapper are all http.Handlers, so they mount the same way:

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

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

func (*App) OnShutdown added in v1.4.0

func (a *App) OnShutdown(fn func(context.Context) error)

OnShutdown registers fn as a teardown hook, run during Shutdown / ShutdownWithContext. This is the one teardown primitive zip exposes: subsystems register their own cleanup at mount time, and reverse-mount teardown falls out for free (see the ordering note below).

Ordering. Hooks run LAST in the shutdown sequence — after listeners stop accepting and after in-flight requests drain — and in LIFO order (reverse registration = reverse mount order). Draining first means a subsystem's teardown never races the requests still using it; LIFO means a dependency mounted before its dependents is torn down after them.

Errors. Every hook runs even if an earlier one fails; all hook errors (and the drain error) are aggregated with errors.Join and returned from Shutdown.

Concurrency. Registration is safe from multiple goroutines. A nil fn is ignored. Registering after Shutdown has begun is a no-op: the hook is dropped (never run) and a warning is logged — there is no longer a shutdown to hook into, and running it immediately would give OnShutdown two meanings depending on timing. Register teardown at mount time, before Shutdown.

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 every transport, then runs teardown hooks. The process is ending, so hooks receive context.Background() — no cancellation or deadline. Use ShutdownWithContext to bound teardown. Idempotent: a second call is a no-op and hooks run at most once.

func (*App) ShutdownWithContext

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

ShutdownWithContext is Shutdown bounded by ctx: ctx bounds the in-flight drain and is passed to every teardown hook (values and deadline). Shares Shutdown's once-guard, so mixing the two still runs hooks once.

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.

func (*App) With added in v1.5.0

func (a *App) With(mw ...Middleware) Router

With returns a Router whose subsequent leaf registrations (Get/Post/…/All) have mw wrapped around the handler at registration time — chi's idiom, pure composition (RateLimit(CSRF(handler))). It does NOT touch the global Use stack and does NOT route through c.Next(); it is the per-route counterpart to Use. Routes registered on the returned Router still obey specificity precedence exactly like any other route.

app.With(RateLimit, CSRF).Post("/v1/keys", mintKey)

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 served on a zip router as an ordinary zip.Handler. To front a whole foreign subtree, register it on a wildcard route — this is THE way to mount stdlib / chi / gin code:

app.All("/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.

func Static added in v1.5.0

func Static(fsys fs.FS, opts ...StaticOption) Handler

Static returns a leaf Handler that serves files from fsys. Mount it on a wildcard route; the "*" capture selects the file:

app.Get("/assets/*", zip.Static(assets))                       // embed.FS
app.Get("/app/*", zip.Static(os.DirFS("dist"), zip.WithIndex("index.html")))

Contract:

  • The subpath is cleaned and checked with fs.ValidPath; any ".." escape or absolute path is rejected fail-closed with 404 — Static can never read outside fsys.
  • A missing file yields c.Next(), so a later more-specific route or a SPA catch-all still wins — never a 500.
  • Sets Content-Type (by extension), Content-Length and Last-Modified; honours HEAD and If-Modified-Since (304). Nothing else — no compression, no byte ranges, no directory listing.

fsys is any fs.FS: an embed.FS for baked-in assets or os.DirFS(dir) for a directory on disk. Both are traversal-safe by construction; the fs.ValidPath gate is defence in depth on top of that.

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 Middleware added in v1.5.0

type Middleware = func(next Handler) Handler

Middleware is a composable request transformer in the classic wrapping form: given the next Handler it returns a Handler that runs around it. This is a DIFFERENT tool from Use — they do different jobs and compose freely:

  • Use(Handler...) registers GLOBAL / prefix middleware. It runs for every matched route (or every route under a Group) in DECLARATION order and chains via c.Next(). Reach for it for ambient cross-cutting concerns that apply broadly: logging, recovery, request-id.

  • Middleware + With + Chain wrap ONE leaf handler explicitly, at registration time, with no c.Next() indirection. Reach for it when a specific endpoint needs a specific pipeline:

    app.With(RateLimit, CSRF).Post("/v1/keys", mintKey)

    wraps mintKey as RateLimit(CSRF(mintKey)): RateLimit is outermost and runs first, CSRF next, the handler last; any layer short-circuits by returning without calling next.

A Middleware body is written by hand, no framework glue:

func RequireCSRF(next zip.Handler) zip.Handler {
    return func(c *zip.Ctx) error {
        if !validCSRF(c) {
            return c.String(403, "bad csrf") // short-circuit
        }
        return next(c) // continue
    }
}

func Chain added in v1.5.0

func Chain(mw ...Middleware) Middleware

Chain composes middleware left-to-right into one Middleware. Chain(a, b, c) nests as a(b(c(handler))): a is outermost (runs first inbound, last outbound), c innermost, wrapping the handler directly. Chain() with no arguments is the identity middleware.

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 StaticOption added in v1.5.0

type StaticOption func(*staticConfig)

StaticOption configures Static. Zero options serve fsys as-is.

func WithIndex added in v1.5.0

func WithIndex(name string) StaticOption

WithIndex serves name (e.g. "index.html") for directory and root requests. Without it a directory request falls through via c.Next().

func WithStripPrefix added in v1.5.0

func WithStripPrefix(prefix string) StaticOption

WithStripPrefix derives the fs path from the request path with prefix removed, instead of from the route's "*" capture. Use it when the captured subpath is not the fs path — e.g. a versioned URL served from an unversioned tree: WithStripPrefix("/static/v2/") maps /static/v2/app.js to app.js.

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