router

package module
v0.57.0 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2026 License: MIT Imports: 58 Imported by: 28

README

go-router

A lightweight, generic HTTP router interface for Go that enables framework agnostic HTTP handling with built in adapters. This package provides an abstraction for routing, making it easy to switch between different HTTP router implementations.

Installation

go get github.com/goliatone/go-router

Overview

go-router provides a common interface for HTTP routing that can be implemented by different HTTP frameworks. Currently includes a Fiber and HTTPRouter with plans to support more frameworks.

HTTPRouter Adapter Constraints

httprouter does not allow a static segment and a wildcard segment (:id or *path) at the same path depth under the same prefix. For example, /admin/exports/:id and /admin/exports/history cannot both be registered in the HTTPRouter adapter.

By default, go-router panics on these conflicts. To log and skip conflicting routes:

app := router.NewHTTPServer(router.WithHTTPRouterConflictPolicy(router.HTTPRouterConflictLogAndSkip))

Path Conflict Modes

The default route path conflict mode is strict for all adapters. In strict mode, static and param siblings (for example /users/bulk/assign-role and /users/bulk/:action) are treated as conflicts.

Fiber can opt into prefer_static, which allows static+param siblings and makes matching deterministic by preferring static routes over param routes.

app := router.NewFiberAdapterWithConfig(router.FiberAdapterConfig{
    PathConflictMode: router.PathConflictModePreferStatic,
})

Catch-all conflict enforcement (/* vs concrete routes) is now opt-in for route validation and Fiber conflict detection. This allows common patterns such as a global fallback route when ordering is deterministic.

Enable catch-all conflict enforcement explicitly when desired:

app := router.NewFiberAdapterWithConfig(router.FiberAdapterConfig{
    PathConflictMode:         router.PathConflictModePreferStatic,
    EnforceCatchAllConflicts: true,
})

For validation helpers:

errs := router.ValidateRouteDefinitionsWithOptions(routes, router.RouteValidationOptions{
    PathConflictMode:         router.PathConflictModePreferStatic,
    EnforceCatchAllConflicts: true,
})

Route lint enforcement (for example bare :id next to static siblings like /users/new) is also opt-in. By default, lints do not fail strict route validation.

errs := router.ValidateRouteDefinitionsWithOptions(routes, router.RouteValidationOptions{
    PathConflictMode:  router.PathConflictModePreferStatic,
    EnforceRouteLints: true,
})

When allowing catch-all routes, keep deterministic ordering enabled (OrderRoutesBySpecificity) so specific routes are registered before catch-all routes.

HTTPRouter only supports strict. Requesting prefer_static with:

router.NewHTTPServer(router.WithHTTPRouterPathConflictMode(router.PathConflictModePreferStatic))

will fail fast with a ROUTE_CONFLICT_MODE_UNSUPPORTED error.

Named Route Collision Policy

Named-route collisions default to replace for backward compatibility. When enabled, the policy only treats a route name as conflicting if it points to a different full path. Reusing the same name on the same path across multiple methods is allowed.

SetName(...) is the public naming API. It now applies names transactionally:

  • replace rebinds the public lookup name
  • skip keeps the existing public binding and leaves the incoming route's public name unchanged
  • error keeps the existing binding, records ROUTE_NAME_CONFLICT, and fails strict startup validation during Init()

Framework-owned helper routes now keep internal runtime names without claiming the public named-route namespace. Static helpers, default websocket routes, and ServeOpenAPI(...) routes still expose a local route name for request context and debugging, but they do not participate in GetRoute(...), ownership validation, or default manifest identity unless you explicitly call SetName(...) on the returned route.

Fiber:

app := router.NewFiberAdapterWithConfig(router.FiberAdapterConfig{
    StrictRoutes:     true,
    NamedRoutePolicy: router.NamedRouteCollisionPolicyError,
})

HTTPRouter:

app := router.NewHTTPServer(
    router.WithHTTPServerStrictRoutes(true),
    router.WithHTTPRouterNamedRoutePolicy(router.NamedRouteCollisionPolicyError),
)

For validation helpers:

errs := router.ValidateRouteDefinitionsWithOptions(routes, router.RouteValidationOptions{
    NamedRoutePolicy: router.NamedRouteCollisionPolicyError,
})

error mode emits ROUTE_NAME_CONFLICT with route-name metadata and fails strict startup validation during Init().

Usage

Basic Example with Fiber
package main

import (
    "github.com/goliatone/go-router"
    "github.com/gofiber/fiber/v2"
)

func main() {
    // Create new Fiber adapter
    app := router.NewFiberAdapter()

    // Add middleware
    app.Router().Use(func(c router.Context) error {
        c.SetHeader("Content-Type", "application/json")
        return c.Next()
    })

    // Add routes
    app.Router().Get("/hello", func(c router.Context) error {
        return c.JSON(200, map[string]string{"message": "Hello World!"})
    })

    // Start server
    app.Serve(":3000")
}
Fiber RPC Mount (go-command/rpc)

Use rpcfiber.MountFiber to add first-class RPC transport routes to a Fiber-backed go-router app.

import (
    "github.com/gofiber/fiber/v2"
    cmdrpc "github.com/goliatone/go-command/rpc"
    "github.com/goliatone/go-router"
    "github.com/goliatone/go-router/rpcfiber"
)

func mountRPC(app router.Server[*fiber.App], rpcServer *cmdrpc.Server) error {
    return rpcfiber.MountFiber(app.Router(), rpcServer)
}

Default mounted routes:

  • POST /api/rpc
  • GET /api/rpc/endpoints

POST /api/rpc decodes payloads using rpc.Server.NewRequestForMethod, injects transport metadata into rpc.RequestMeta, and invokes the method using rpc.Server.Invoke.

You can customize route paths and add request hooks:

err := rpcfiber.MountFiber(
    app.Router(),
    rpcServer,
    rpcfiber.WithInvokePath("/api/:tenant/rpc"),
    rpcfiber.WithMetaExtractor(func(c router.Context, meta *cmdrpc.RequestMeta) {
        meta.Scope = map[string]any{
            "traceId": c.Header("X-Trace-ID"),
        }
    }),
    rpcfiber.WithBeforeInvokeHook(func(c router.Context, method string, payload any) error {
        // Optional pre-invoke validation or observability hook.
        return nil
    }),
)
if err != nil {
    panic(err)
}
Fiber SSE Runtime Stream

Use eventstream for transport-neutral runtime events and ssefiber for a Fiber-first SSE endpoint.

ssefiber is the supported v1 transport for native go-router handlers on Fiber. If you need bidirectional messaging or transport-specific room/session behavior, use the websocket support instead. If you need server-to-browser push with replay, cursor resume, and browser failover, use SSE.

import (
    "encoding/json"

    "github.com/gofiber/fiber/v2"
    "github.com/goliatone/go-router"
    "github.com/goliatone/go-router/eventstream"
    "github.com/goliatone/go-router/ssefiber"
)

func mountRuntimeStream(app router.Server[*fiber.App]) error {
    stream := eventstream.New(
        eventstream.WithBufferSize(512),
        eventstream.WithSubscriberBuffer(32),
        eventstream.WithMatcher(eventstream.ExactMatch),
    )

    if err := ssefiber.MountFiber(
        app.Router(),
        ssefiber.WithPath("/api/runtime/events"),
        ssefiber.WithStream(stream),
        ssefiber.WithScopeResolver(func(ctx router.Context) (eventstream.Scope, error) {
            return eventstream.Scope{
                "tenant": ctx.Header("X-Tenant-ID"),
                "channel": "admin.commands",
            }, nil
        }),
    ); err != nil {
        return err
    }

    acceptedPayload, _ := json.Marshal(map[string]any{
        "command": "esign.agreements.notify_reviewers",
        "status": "accepted",
        "command_id": "cmd_123",
        "resource_id": "agreement_42",
    })
    stream.Publish(eventstream.Scope{
        "tenant": "t1",
        "channel": "admin.commands",
    }, eventstream.Event{
        Name:    "lifecycle",
        Payload: acceptedPayload,
    })

    resourcePayload, _ := json.Marshal(map[string]any{
        "resource": "esign.agreement",
        "resource_id": "agreement_42",
        "change": "state_changed",
        "state": "review_closed",
    })
    stream.Publish(eventstream.Scope{
        "tenant": "t1",
        "channel": "admin.commands",
    }, eventstream.Event{
        Name:    "resource_state",
        Payload: resourcePayload,
    })

    return nil
}

Browser usage:

import createSSEClient from "@goliatone/go-router-sse-client";

const client = createSSEClient({
    url: "/api/runtime/events",
    getHeaders: () => ({
        Authorization: `Bearer ${token}`,
    }),
    onEvent: (event) => {
        if (event.name === "lifecycle") {
            reconcileCommandState(event.payload);
        }
    },
    onRequestSnapshot: () => {
        refreshAuthoritativeSnapshot();
    },
});

client.start();

Embedded asset serving:

router.RegisterSSEHandlers(app.Router())

This exposes the bundled browser client from the router package itself:

  • /sseclient/client.min.js
  • /sseclient/client.js
  • /sseclient/client.js.map
  • /sseclient/client.mjs
  • /sseclient/client.d.ts
  • /sseclient/info
Adapting net/http Handlers

Use HandlerFromHTTP to reuse standard http.Handler code. For direct access to http.Request and http.ResponseWriter, use the helper AsHTTPContext.

app.Router().Get("/export", router.HandlerFromHTTP(exportHandler))

app.Router().Get("/stream", func(c router.Context) error {
    if httpCtx, ok := router.AsHTTPContext(c); ok {
        httpCtx.Response().Write([]byte("chunk"))
        if fl, ok := httpCtx.Response().(http.Flusher); ok {
            fl.Flush()
        }
        return nil
    }
    return c.SendStream(strings.NewReader("fallback"))
})

Note: on Fiber, net/http streaming is buffered by fasthttp. Flush() is best-effort (headers only) unless you use a streaming adapter. For true streaming in Fiber, prefer SendStream from go-router handlers.

Controlling view/locals merge

When PassLocalsToViews is enabled, go-router merges handler locals into the view bind. By default the view bind wins on key collisions and a warning is logged. You can override this with a custom strategy:

app := router.NewFiberAdapterWithConfig(router.FiberAdapterConfig{
    MergeStrategy: func(key string, viewVal, localVal any, logger router.Logger) (any, bool) {
        return localVal, true // prefer locals for this app
    },
})

Plain Fiber handlers can reuse the merge logic without a go-router context:

merged, err := router.MergeLocalsWithViewData(c, myLogger, nil, router.ViewContext{"status": 404})
if err != nil {
    return err
}
return c.Render("error", merged)
Route Groups
api := app.Router().Group("/api")
{
    api.Post("/users", createUser(store)).Name("user.create")
    api.Get("/users", listUsers(store)).Name("user.list")
    api.Get("/users/:id", getUser(store)).Name("user.get")
    api.Put("/users/:id", updateUser(store)).Name("user.update")
    api.Delete("/users/:id", deleteUser(store)).Name("user.delete")
}
Builder
api := app.Router().Group("/api")

builder := router.NewRouteBuilder(api)

users := builder.Group("/users")
{
    users.NewRoute().
        POST().
        Path("/").
        Description("Create a new user").
        Tags("User").
        Handler(createUser(store)).
        Name("user.create")

    users.NewRoute().
        GET().
        Path("/").
        Description("List all users").
        Tags("User").
        Handler(listUsers(store)).
        Name("user.list")

    users.NewRoute().
        GET().
        Path("/:id").
        Description("Get user by ID").
        Tags("User").
        Handler(getUser(store)).
        Name("user.get")

    users.NewRoute().
        PUT().
        Path("/:id").
        Description("Update user by ID").
        Tags("User").
        Handler(updateUser(store)).
        Name("user.update")

    users.NewRoute().
        DELETE().
        Path("/:id").
        Description("Delete user by ID").
        Tags("User").
        Handler(deleteUser(store)).
        Name("user.delete")

    users.BuildAll()
}
Namespace Resolver

go-router includes a generic namespace + route-key resolver for projects that want stable route keys instead of hardcoded path strings.

type Surface string

const (
    SurfacePublic    Surface = "public"
    SurfaceProtected Surface = "protected"
)

paths := router.NewNamespaceResolver(
    map[Surface]string{
        SurfacePublic:    "/public/api/v1",
        SurfaceProtected: "/api/v1",
    },
    map[Surface]map[string]string{
        SurfaceProtected: {
            "wizard.session.create": "/wizard/sessions",
            "wizard.session.get":    "/wizard/sessions/:session_id",
        },
    },
)

full, err := paths.Resolve(SurfaceProtected, "wizard.session.get")
if err != nil {
    return err
}
// full == "/api/v1/wizard/sessions/:session_id"

Grouped-router usage:

protected := app.Router().Group(paths.MustNamespace(SurfaceProtected))

protected.Get(
    paths.MustRelative(SurfaceProtected, "wizard.session.get"),
    getWizardSessionHandler,
)

Migration note (wizard-flow):

// Before: app-local resolver implementation.
// After: keep your namespace + route tables in app code and use go-router's resolver.
paths := router.NewNamespaceResolver(
    namespaceTable, // map[Surface]string
    routeTable,     // map[Surface]map[string]string
)
Route Ownership Validation

Use ValidateOwnedRouteSets when a host app wants to verify mounted module routes against explicit ownership rules.

routeSets := []router.OwnedRouteSet{
    {
        Owner: "host",
        Routes: app.Router().Routes(),
    },
    {
        Owner: "translations",
        Routes: translationsRoutes,
    },
}

policy := router.RouteOwnershipPolicy{
    ReservedRoots: []router.ReservedRootClaim{
        {Owner: "host", Root: "/admin"},
        {Owner: "host", Root: "/api"},
    },
    Owners: []router.OwnerRoutePolicy{
        {
            Owner:             "translations",
            AllowedPrefixes:   []string{"/modules/translations"},
            RouteNamePrefixes: []string{"translations."},
        },
    },
}

errs := router.ValidateOwnedRouteSets(routeSets, policy)
if len(errs) > 0 {
    panic(errors.Join(errs...))
}

For a strict host/module boot profile, start from the built-in strict defaults and layer owner rules on top:

policy := router.StrictRouteOwnershipPolicy()
policy.ReservedRoots = []router.ReservedRootClaim{
    {Owner: "host", Root: "/admin"},
    {Owner: "host", Root: "/api"},
}
policy.Owners = []router.OwnerRoutePolicy{
    {
        Owner:             "translations",
        AllowedPrefixes:   []string{"/modules/translations"},
        RouteNamePrefixes: []string{"translations."},
    },
}

This is complementary to NamespaceResolver: the resolver gives stable paths, and the ownership validator enforces who is allowed to claim them.

Route Manifest And Diff

Use manifests for deterministic CI snapshots and upgrade review.

before := router.BuildRouteManifest(moduleRoutes)
after := router.BuildRouterManifest(app.Router())

diff := router.DiffRouteManifests(before, after)
for _, entry := range diff.Added {
    fmt.Printf("added %s %s (%s)\n", entry.Method, entry.Path, entry.Name)
}

Manifest entries are sorted by path, method, and route name. Internal helper routes are still included, but their Name field is blank in the default manifest so CI diffs reflect public API identity instead of framework-owned helper names.

If you need the runtime/helper names for debugging or internal inspection, use the separate opt-in API:

internalManifest := router.BuildRouterManifestWithInternalNames(app.Router())
rawManifest := router.BuildRouteManifestWithInternalNames(moduleRoutes)
Strict Host Boot Profile
app := router.NewFiberAdapterWithConfig(router.FiberAdapterConfig{
    StrictRoutes:     true,
    NamedRoutePolicy: router.NamedRouteCollisionPolicyError,
    PathConflictMode: router.PathConflictModeStrict,
})

policy := router.StrictRouteOwnershipPolicy()
policy.ReservedRoots = []router.ReservedRootClaim{
    {Owner: "host", Root: "/admin"},
    {Owner: "host", Root: "/api"},
}

errs := router.ValidateOwnedRouteSets(routeSets, policy)
if len(errs) > 0 {
    panic(errors.Join(errs...))
}

manifest := router.BuildRouterManifest(app.Router())
_ = manifest

Middleware

go-router includes several built in middleware components that provide common functionality for HTTP request processing.

Request ID Middleware

Generates and manages unique request identifiers for tracing and logging purposes.

import "github.com/goliatone/go-router/middleware/requestid"

// Use default configuration
app.Use(requestid.New())

// Custom configuration
app.Use(requestid.New(requestid.Config{
    Header:     "X-Custom-Request-ID",
    Generator:  func() string { return "custom-" + uuid.NewString() },
    ContextKey: "req_id",
}))

Features:

  • Generates UUID based request IDs by default
  • Configurable header name (default: X-Request-ID)
  • Custom ID generator function support
  • Stores ID in context for handler access
  • Skippable with custom skip function
Route Context Middleware

Injects route information into the request context for template rendering and handler access.

import "github.com/goliatone/go-router/middleware/routecontext"

// Using default configuration (ExportAsMap: true)
app.Use(routecontext.New())

// Custom configuration with consolidated map export
app.Use(routecontext.New(routecontext.Config{
    ExportAsMap:         true,  // Default: exports as single map
    TemplateContextKey:  "route_info",
    CurrentRouteNameKey: "route_name",
    CurrentParamsKey:    "params",
    CurrentQueryKey:     "query",
}))

// Configuration with individual key exports
app.Use(routecontext.New(routecontext.Config{
    ExportAsMap:         false, // Exports each key individually
    CurrentRouteNameKey: "route_name",
    CurrentParamsKey:    "params",
    CurrentQueryKey:     "query",
}))

Features:

  • Extracts current route name, parameters, and query strings
  • Two export modes controlled by ExportAsMap field:
    • Map mode (ExportAsMap: true, default): Stores data in a consolidated map under TemplateContextKey
    • Individual mode (ExportAsMap: false): Stores each key separately in context
  • Default storage under "template_context" key in map mode
  • Perfect for template rendering with route aware content
  • Flexible access patterns for different use cases

Template Usage (Map Mode - Default):

<!-- Access route information via consolidated map -->
{{ template_context.current_route_name }}
{{ template_context.current_params.user_id }}
{{ template_context.current_query.page }}

Template Usage (Individual Mode):

<!-- Access route information via individual keys -->
{{ route_name }}
{{ params.user_id }}
{{ query.page }}

Handler Access (Map Mode):

app.Get("/users/:id", func(c router.Context) error {
    routeData := c.Locals("template_context").(map[string]any)
    routeName := routeData["current_route_name"].(string)
    params := routeData["current_params"].(map[string]string)
    return c.JSON(200, fiber.Map{"route": routeName, "params": params})
})

Handler Access (Individual Mode):

app.Get("/users/:id", func(c router.Context) error {
    routeName := c.Locals("route_name").(string)
    params := c.Locals("params").(map[string]string)
    query := c.Locals("query").(map[string]string)
    return c.JSON(200, fiber.Map{"route": routeName, "params": params, "query": query})
})
Flash Middleware

Provides flash message functionality for displaying temporary messages across redirects using cookie based storage.

import "github.com/goliatone/go-router/middleware/flash"

// Use default configuration
app.Use(flash.New())

// Custom configuration
app.Use(flash.New(flash.Config{
    ContextKey: "flash_data",
    Flash:      customFlashInstance,
}))

Features:

  • Cookie based flash message storage that survives redirects
  • Automatic injection of flash data into request context
  • Integration with existing flash utility for setting messages
  • Configurable context key for accessing flash data
  • Skippable with custom skip function

Cookie Defaults (safe by default):

  • Path: "/", HTTPOnly: true, SameSite: "Lax" (set Secure: true for HTTPS deployments)
  • To allow client-side JS to read the cookie (client-rendered UIs), configure flash.Config{ClientAccessible: true}

Toast Messages (SSR-friendly):

import flashmw "github.com/goliatone/go-router/middleware/flash"
import flash "github.com/goliatone/go-router/flash"

f := flash.New(flash.Config{
    Secure:              true,
    DefaultMessageTitle: "Notice",
})
app.Use(flashmw.New(flashmw.Config{Flash: f}))

// In a POST handler:
flash.SetMessage(c, flash.Message{Type: "success", Text: "Saved"})
return c.Redirect("/admin")

Handler Usage:

// Access flash data in handlers
app.Get("/", func(c router.Context) error {
    flashData := c.Locals("flash").(router.ViewContext)
    return c.Render("index", flashData)
})

Template Usage:

{% if flash.error %}
<div class="p-4 mb-4 text-sm text-red-800 rounded-lg bg-red-50 border border-red-400" role="alert">
    <span class="font-medium">Authentication Failed!</span>
    {% if flash.error_message %}
    <p>{{ flash.error_message }}</p>
    {% else %}
    Please check your credentials and try again.
    {% endif %}
</div>
{% endif %}
FeatureGate Middleware

Integrates go-featuregate with go-router by injecting scope claims into the request context so handlers can call gate.Enabled directly.

import (
    "github.com/goliatone/go-featuregate/gate"
    featuregatemw "github.com/goliatone/go-router/middleware/featuregate"
)

mw := featuregatemw.New(
    featuregatemw.WithClaimsResolver(func(ctx router.Context) (gate.ActorClaims, error) {
        return gate.ActorClaims{
            TenantID:  ctx.Param("tenant_id"),
            OrgID:     ctx.Param("org_id"),
            SubjectID: ctx.Locals("user_id").(string),
        }, nil
    }),
    featuregatemw.WithActorResolver(func(ctx router.Context) gate.ActorRef {
        return gate.ActorRef{ID: ctx.Locals("user_id").(string)}
    }),
)

app.Use(mw)

app.Get("/users", func(ctx router.Context) error {
    allowed, err := gate.Enabled(ctx.Context(), "users.read")
    if err != nil {
        return err
    }
    if !allowed {
        return router.NewNotFoundError("not found")
    }
    return ctx.JSON(200, map[string]string{"ok": "true"})
})

Features:

  • Claims resolver injects tenant/org/user scope into the request context.
  • WithStrict(true) returns BAD_REQUEST when the resolver fails or when no tenant/org/user (subject) ID is provided.
  • Actor metadata is optional and stored in context (see featuregatemw.ActorFromContext); go-featuregate does not consume it automatically.
  • Optional helper featuregatemw.Context returns the standard context.Context.

View Engine

View Engine Initialization

go-router includes a powerful and flexible view engine initializer that works seamlessly with frameworks that support fiber.Views (like Fiber itself). It's built on pongo2, offering a Django like template syntax, and handles both live reloading for development and high performance embedded assets for production.

The core function is router.InitializeViewEngine(config). It takes a configuration object that implements the ViewConfigProvider interface.

Key Features
  • Embedded & Live Modes: Use go:embed for single binary production builds, or load templates directly from the OS for rapid development.
  • Composite Filesystems: In embedded mode, you can layer multiple filesystems. This is perfect for theme overriding, where a theme's templates can transparently override a base set of templates.
  • Automatic Asset Handling: Template functions css(glob) and js(glob) automatically find your versioned assets (e.g., main-*.css) and generate the correct HTML tags.
  • Intelligent Pathing: The engine automatically handles subdirectories in embedded filesystems, so your paths are always clean and relative to your declared asset/template roots.
Quick Start: File Based Templates

For a quick start you can skip building a custom config struct and use SimpleViewConfig:

cfg := router.NewSimpleViewConfig("./views")
viewEngine, err := router.InitializeViewEngine(cfg)
if err != nil {
    log.Fatalf("init views: %v", err)
}

app := fiber.New(fiber.Config{Views: viewEngine})

Asset helpers are opt-in cfg.WithAssets("./public", "css", "js") when you have static files. Templates use Django/Pongo2 syntax, for example {{ title }} (not Go's {{ .Title }}).

If you want paths relative to your module root (instead of the current working directory), use NewSimpleViewConfigFromModuleRoot("./views"). For embedded templates, you can use NewSimpleViewConfigFS("templates", embedFS).

Configuration (ViewConfigProvider Interface)

Your configuration struct must provide getters for the following options:

Option Type Description
GetEmbed() bool (Required) true to use embedded fs.FS filesystems, false to load from the operating system.
GetDebug() bool Enables debug logging from the template engine.
GetReload() bool If true, templates are reloaded on every request. Ideal for development.
GetExt() string The file extension for your templates (e.g., .html, .p2).
GetTemplateFunctions() map[string]any A map of custom functions to register with the template engine.
Embedded Mode Options
GetTemplatesFS() []fs.FS (Required) A slice of fs.FS filesystems containing your templates. Order matters for overrides (first found wins).
GetAssetsFS() fs.FS (Optional) Embedded filesystem for your static assets. Required only if you enable asset helpers in embedded mode.
GetDirFS() string The path inside GetTemplatesFS to the root of your templates (e.g., "templates").
GetAssetsDir() string The path inside GetAssetsFS to the root of your assets (e.g., "public"). Optional when asset helpers are disabled.
GetDevDir() string An absolute OS path to a directory of override templates. These take highest priority, perfect for local development without changing embedded files.
Live (Non-Embedded) Mode Options
GetDirOS() string (Required) The absolute or relative OS path to your templates directory.
GetAssetsDir() string The absolute or relative OS path to your assets directory. Leave empty to disable asset helpers.
Asset URL Generation
GetCSSPath() string The subdirectory within your AssetsDir where CSS files are located (e.g., "css"). Optional when not using the css helper.
GetJSPath() string The subdirectory within your AssetsDir where JS files are located (e.g., "js"). Optional when not using the js helper.
GetURLPrefix() string An optional prefix to add to all generated asset URLs. Useful for serving assets from a namespaced path like /static.

Example 1: Embedded Mode for Production

This setup is ideal for creating a self contained, single binary application.

Directory Structure:

.
├── assets/
│   ├── css/main-a1b2c3d4.css
│   └── js/app-e5f6g7h8.js
├── templates/
│   ├── layouts/base.html
│   └── index.html
└── main.go

main.go:

package main

import (
	"embed"
	"io/fs"
	"log"

	"github.com/gofiber/fiber/v2"
	"github.com/goliatone/go-router"
)

//go:embed templates
var templateFS embed.FS

//go:embed assets
var assetFS embed.FS

type AppConfig struct {
    // app settings
}
func (c *AppConfig) GetEmbed() bool         { return true }
func (c *AppConfig) GetDebug() bool         { return true }
func (c *AppConfig) GetReload() bool        { return false } // a
func (c *AppConfig) GetExt() string         { return ".html" }
func (c *AppConfig) GetDirFS() string       { return "templates" } // root of templates in templateFS
func (c *AppConfig) GetAssetsDir() string   { return "assets" } // Root of assets in assetFS
func (c *AppConfig) GetCSSPath() string     { return "css" }
func (c *AppConfig) GetJSPath() string      { return "js" }
func (c *AppConfig) GetURLPrefix() string   { return "static" } // URL will be /static/css/...
func (c *AppConfig) GetDevDir() string      { return "" } // no dev overrides
func (c *AppConfig) GetTemplatesFS() []fs.FS { return []fs.FS{templateFS} }
func (c *AppConfig) GetAssetsFS() fs.FS     { return assetFS }
// live mode options are ignored when embed is true
func (c *AppConfig) GetDirOS() string { return "" }
func (c *AppConfig) GetTemplateFunctions() map[string]any { return nil }

func main() {
    config := &AppConfig{}

    viewEngine, err := router.InitializeViewEngine(config)
    if err != nil {
        log.Fatalf("Failed to init view engine: %v", err)
    }

    app := fiber.New(fiber.Config{
        Views: viewEngine,
    })

    // IMPORTANT: Serve your static files with the same prefix!
    // The router only generates URLs; it doesn't serve files.
    // router.SubFS is used to serve the `assets` directory content.
    staticFS, err := router.SubFS(assetFS, "assets")
    if err != nil {
        log.Fatalf("Failed to scope assets: %v", err)
    }
    app.Static("/static", filesystem.New(filesystem.Config{
        Root: http.FS(staticFS),
    }))

    app.Get("/", func(c *fiber.Ctx) error {
        return c.Render("index", fiber.Map{"Title": "Welcome"})
    })

    log.Fatal(app.Listen(":3000"))
}

templates/layouts/base.html:

<!DOCTYPE html>
<html>
<head>
    <title>{{ Title }}</title>
    {{ css("main-*.css") | safe }}
</head>
<body>
    {% block content %}{% endblock %}
    {{ js("app-*.js") | safe }}
</body>
</html>

This will render <link href="/static/css/main-a1b2c3d4.css"> in the final HTML.


Example 2: Live Mode for Development

This setup loads files directly from your disk. Using SimpleViewConfig keeps the configuration minimal while enabling reloads and asset helpers.

func main() {
    cfg := router.NewSimpleViewConfig("./templates").
        WithAssets("./assets", "css", "js") // optional

    viewEngine, err := router.InitializeViewEngine(cfg)
    if err != nil {
        log.Fatalf("Failed to init view engine: %v", err)
    }

    app := fiber.New(fiber.Config{
        Views: viewEngine,
    })

    // serve assets directly from the filesystem path
    app.Static("/", "./assets")

    // define your routes...
    log.Fatal(app.Listen(":3000"))
}

This will render <link href="/css/main-a1b2c3d4.css"> in the final HTML, which is served by app.Static.

Pro Tip: Generating Configuration

Manually implementing the ViewConfigProvider interface for every project can be repetitive. You can accelerate this process by defining your configuration in a JSON or YAML file and using the go-generators tool to automatically generate the required Go struct and methods.

1. Define your configuration in config/app.json:

{
  "views": {
    "embed": true,
    "debug": true,
    "reload": false,
    "ext": ".html",
    "dir_fs": "views",
    "assets_dir": "public",
    "css_path": "css",
    "js_path": "js",
    "url_prefix": "static"
  }
}

2. Run the generator: The generator will parse your JSON file, create a corresponding Go struct (ViewsConfig), and automatically implement all the necessary methods of the ViewConfigProvider interface.

go run github.com/goliatone/go-generators/cmd/config-gen --source ./config/app.json --key views --type ViewsConfig

3. Use the generated config: Now you can simply load your configuration from the file and pass it directly to the view engine initializer.

package main

import (
    "path/to/your/generated/config"
    "github.com/goliatone/go-router"
    // ...
)

func main() {
    // load config from file
    appConfig, err := config.Load()
    if err != nil {
        // handle error
    }

    // the generated appConfig.Views field already implements ViewConfigProvider
    viewEngine, err := router.InitializeViewEngine(appConfig.Views)
    if err != nil {
        log.Fatalf("Failed to init view engine: %v", err)
    }

    //... setup Fiber app
}

This approach keeps your configuration clean and separate from your application logic while eliminating boilerplate code.

WebSocket Support

go-router provides comprehensive WebSocket support with an event driven architecture, room management, and extensive middleware capabilities. The WebSocket implementation works seamlessly with existing HTTP routers and provides both simple and advanced usage patterns.

Quick Start
// Simple WebSocket handler
app.Router().Get("/ws", router.NewWSHandler(func(ctx context.Context, client router.WSClient) error {
    // Handle messages
    client.OnMessage(func(ctx context.Context, data []byte) error {
        fmt.Printf("Received: %s\n", data)
        return client.Send([]byte("Echo: " + string(data)))
    })

    // Wait for disconnection
    <-ctx.Done()
    return nil
}))
Features
  • Event driven architecture with connect/disconnect/message handlers
  • Room management with join/leave and targeted broadcasting
  • Middleware system including authentication, logging, metrics, rate limiting, and panic recovery
  • Context support throughout the API for cancellation and request scoped data
  • JSON message handling with structured event routing
  • Client state management with get/set operations
  • Automatic connection lifecycle management with ping/pong handling

For complete WebSocket documentation, examples, and advanced features, see README_WEBSOCKET.md.

Error Handling Policy

This project follows a consistent error handling strategy to ensure reliability and maintainability across the WebSocket and HTTP components.

Error Classification
1. Recoverable Errors (Return to Caller)

These errors should be returned to the calling function to allow for graceful handling and recovery:

  • Validation errors: Invalid input parameters, malformed data
  • Authentication/Authorization failures: Token validation, permission checks
  • Configuration errors: Missing required configuration, invalid settings
  • External service failures: Database connection errors, API call failures
  • Resource exhaustion: Rate limiting violations, connection limits reached

Pattern:

func ProcessRequest(data []byte) error {
    if len(data) == 0 {
        return fmt.Errorf("empty data provided")
    }
    // ... processing logic
    return nil
}
2. System Errors (Log Centrally)

These errors represent system level issues that should be logged centrally for monitoring and debugging:

  • Internal server errors: Unexpected panics, nil pointer dereferences
  • Infrastructure failures: Network timeouts, disk I/O errors
  • Background operation failures: Cleanup operations, periodic tasks
  • WebSocket connection errors: Unexpected disconnections, protocol violations
  • Hub/Room management errors: Client registration failures, broadcast errors

Pattern:

func (h *WSHub) broadcastToAll(message []byte) {
    h.clientsMu.RLock()
    defer h.clientsMu.RUnlock()

    for client := range h.clients {
        if err := client.WriteMessage(message); err != nil {
            h.logger.Error("Failed to send message to client",
                "client_id", client.ID(),
                "error", err)
            // Continue with other clients - don't return error
        }
    }
}
Logger Requirements

All background components and long running operations must have access to a structured logger:

  • WSHub: For client management and broadcasting errors
  • Room: For room specific operation failures
  • WSClient: For connection specific errors
  • Middleware: For request processing errors
Error Context

When logging errors, always include relevant context:

logger.Error("Operation failed",
    "operation", "client_registration",
    "client_id", client.ID(),
    "room_id", roomID,
    "error", err)
Testing Error Paths

All error handling paths should be testable:

  • Use dependency injection for external services
  • Provide mock implementations for testing
  • Include error scenarios in unit tests
  • Validate error messages and context

API Reference

Server Interface
type Server[T any] interface {
    Router() Router[T]
    WrapHandler(HandlerFunc) any
    WrappedRouter() T
    Serve(address string) error
    Shutdown(ctx context.Context) error
}
Router Interface
type Router[T any] interface {
    Handle(method HTTPMethod, path string, handler ...HandlerFunc) RouteInfo
    Group(prefix string) Router[T]
    Use(args ...any) Router[T]
    Get(path string, handler HandlerFunc) RouteInfo
    Post(path string, handler HandlerFunc) RouteInfo
    Put(path string, handler HandlerFunc) RouteInfo
    Delete(path string, handler HandlerFunc) RouteInfo
    Patch(path string, handler HandlerFunc) RouteInfo
}
Context Interface
type Context interface {
    Method() string
    Path() string
    Param(name string) string
    Query(name string) string
    QueryValues(name string) []string
    Queries() map[string]string
    Status(code int) Context
    Send(body []byte) error
    SendStream(r io.Reader) error
    JSON(code int, v any) error
    NoContent(code int) error
    Bind(any) error
    Context() context.Context
    SetContext(context.Context)
    Header(string) string
    SetHeader(string, string)
    Next() error
}

Query precedence: Query and Queries keep the adapter’s single-value behavior (first/last depending on adapter). QueryValues returns all values in request order. If you accept comma-delimited values, split those explicitly in your handler.

Metadata Generation

go-router provides a powerful schema metadata extraction facility that analyzes Go structs using reflection to generate rich metadata about types, fields, relationships, and tags. This is particularly useful for generating OpenAPI schemas, database migrations, and API documentation.

Overview

The core function ExtractSchemaFromType() takes a Go type and returns comprehensive metadata including:

  • Field information: types, validation rules, JSON schemas
  • Relationship mapping: has-one, has-many, belongs-to, many-to-many relationships
  • Tag metadata: struct tags from json, bun, validation, and custom tags
  • Type hierarchy: transformation paths for complex nested types
  • Original Go type information: field names, types, and package paths
Basic Usage
package main

import (
    "fmt"
    "reflect"
    "github.com/goliatone/go-router"
)

type User struct {
    ID       int64     `json:"id" bun:"id,pk,notnull" validate:"required"`
    Name     string    `json:"name" bun:"name,notnull" validate:"min=1"`
    Email    *string   `json:"email,omitempty" bun:"email" validate:"email"`
    Age      int       `json:"age" bun:"age"`
    Posts    []Post    `bun:"rel:has-many,join:id=user_id" json:"posts,omitempty"`
}

type Post struct {
    ID     int64  `json:"id" bun:"id,pk"`
    Title  string `json:"title" bun:"title,notnull"`
    UserID int64  `json:"user_id" bun:"user_id"`
}

func main() {
    // Extract basic metadata
    metadata := router.ExtractSchemaFromType(reflect.TypeOf(User{}))

    fmt.Printf("Schema: %s\n", metadata.Name)
    fmt.Printf("Properties: %d\n", len(metadata.Properties))
    fmt.Printf("Relationships: %d\n", len(metadata.Relationships))
}
Advanced Configuration

The metadata extraction supports extensive customization through ExtractSchemaFromTypeOptions:

type ExtractSchemaFromTypeOptions struct {
    // Table naming functions
    GetTableName      func(t reflect.Type) string
    ToSnakeCasePlural func(s string) string
    ToSingular        func(s string) string

    // Metadata inclusion options
    IncludeOriginalNames bool // Include original Go field names
    IncludeOriginalTypes bool // Include original Go types
    IncludeTagMetadata   bool // Include all struct tags
    IncludeTypeMetadata  bool // Include type hierarchy info

    // Tag processing
    CustomTagHandlers map[string]func(tag string) any // Handle custom tags
    TagPriority       []string                        // Order of tag precedence

    // Field filtering and transformation
    SkipUnexportedFields *bool                                // Control unexported field inclusion
    SkipAnonymousFields  *bool                                // Control anonymous field inclusion
    CustomFieldFilter    func(field reflect.StructField) bool // Custom field inclusion logic
    FieldNameTransformer func(fieldName string) string        // Custom field name transformation
    PropertyTypeMapper   func(t reflect.Type) PropertyInfo    // Custom type mapping
}
Enhanced Metadata Example
// Enable all metadata features
opts := router.ExtractSchemaFromTypeOptions{
    IncludeOriginalNames: true,
    IncludeOriginalTypes: true,
    IncludeTagMetadata:   true,
    IncludeTypeMetadata:  true,
    TagPriority:          []string{"json", "bun", "validate"},
    CustomTagHandlers: map[string]func(tag string) any{
        "validate": parseValidationRules,
    },
}

metadata := router.ExtractSchemaFromType(reflect.TypeOf(User{}), opts)

// Access enhanced property information
for name, prop := range metadata.Properties {
    fmt.Printf("Field: %s\n", name)
    fmt.Printf("  Original Name: %s\n", prop.OriginalName)
    fmt.Printf("  Original Type: %s\n", prop.OriginalType)
    fmt.Printf("  All Tags: %v\n", prop.AllTags)
    fmt.Printf("  Transform Path: %v\n", prop.TransformPath)
    fmt.Printf("  Package: %s\n", prop.GoPackage)
}
Relationship Support

The metadata extractor automatically detects and maps relationships from struct tags:

Has-One Relationships
type User struct {
    Profile Profile `bun:"rel:has-one,join:id=user_id" json:"profile"`
}
Has-Many Relationships
type User struct {
    Posts []Post `bun:"rel:has-many,join:id=user_id" json:"posts"`
}
Belongs-To Relationships
type Post struct {
    UserID int64 `bun:"user_id" json:"user_id"`
    User   *User `bun:"rel:belongs-to,join:user_id=id" json:"user"`
}
Many-to-Many Relationships
type Order struct {
    Items []Item `bun:"m2m:order_to_items,join:Order=Item" json:"items"`
}
Custom Tag Handlers

Process custom validation or business logic tags:

func parseValidationRules(tag string) any {
    rules := make(map[string]any)
    parts := strings.Split(tag, ",")
    for _, part := range parts {
        if strings.HasPrefix(part, "min=") {
            rules["minimum"] = parseMinValue(part)
        }
        if strings.HasPrefix(part, "max=") {
            rules["maximum"] = parseMaxValue(part)
        }
        if part == "required" {
            rules["required"] = true
        }
    }
    return rules
}

opts := router.ExtractSchemaFromTypeOptions{
    CustomTagHandlers: map[string]func(tag string) any{
        "validate": parseValidationRules,
    },
}
Field Filtering and Transformation
// Helper function to create bool pointers
func boolPtr(b bool) *bool {
    return &b
}

opts := router.ExtractSchemaFromTypeOptions{
    // Include unexported fields
    SkipUnexportedFields: boolPtr(false),

    // Custom field filtering
    CustomFieldFilter: func(field reflect.StructField) bool {
        return !strings.HasPrefix(field.Name, "internal")
    },

    // Transform field names
    FieldNameTransformer: func(fieldName string) string {
        return "api_" + strings.ToLower(fieldName)
    },
}
Property Information

Each field generates a PropertyInfo struct containing:

type PropertyInfo struct {
    // OpenAPI schema fields
    Type         string                  `json:"type"`
    Format       string                  `json:"format,omitempty"`
    Description  string                  `json:"description,omitempty"`
    Required     bool                    `json:"required"`
    Nullable     bool                    `json:"nullable"`
    ReadOnly     bool                    `json:"read_only"`
    WriteOnly    bool                    `json:"write_only"`
    Items        *PropertyInfo           `json:"items,omitempty"`

    // Enhanced metadata (when enabled)
    OriginalName  string            `json:"originalName,omitempty"`  // Go field name
    OriginalType  string            `json:"originalType,omitempty"`  // Go type string
    OriginalKind  reflect.Kind      `json:"originalKind,omitempty"`  // Go kind
    AllTags       map[string]string `json:"allTags,omitempty"`       // All struct tags
    TransformPath []string          `json:"transformPath,omitempty"` // Type transformation steps
    GoPackage     string            `json:"goPackage,omitempty"`     // Package path
    CustomTagData map[string]any    `json:"customTagData,omitempty"` // Custom tag results
}
Vendor Extensions
  • Apply crud:"label" (or crud:"label:<field>") to the struct property that should act as the default display label for the resource.
  • GetResourceMetadata captures tag metadata by default and surfaces the selected property in the generated OpenAPI schema as:
components:
  schemas:
    article:
      type: object
      x-formgen-label-field: "title"
      properties:
        title:
          type: string
  • Downstream tools (e.g., go-crud, go-formgen) can read the extension to pick consistent labels without recalculating them.
Pagination & Query Parameters
  • GetResourceMetadata publishes reusable query parameter components under #/components/parameters, keeping defaults and descriptions in one place:
components:
  parameters:
    Limit:
      name: limit
      in: query
      required: false
      description: Maximum number of records to return (default 25)
      schema:
        type: integer
        default: 25
    Offset:
      name: offset
      in: query
      required: false
      description: Number of records to skip before starting to return results (default 0)
      schema:
        type: integer
        default: 0
  • Collection routes reference the shared components via $ref while keeping field filter operators inline:
paths:
  /articles:
    get:
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
        - $ref: "#/components/parameters/Include"
        - $ref: "#/components/parameters/Select"
        - $ref: "#/components/parameters/Order"
        - name: "{field}"
          in: query
          description: Filter by field value (e.g. name=John)
          schema:
            type: string
  • Downstream generators can reuse the parameter definitions directly (and override defaults if needed) instead of parsing duplicated inline metadata.
Relation Metadata (x-formgen-relations)
  • Register a relation metadata provider so the aggregator can export valid include paths and filter hints:
provider := router.NewDefaultRelationProvider()

aggregator := router.NewMetadataAggregator().
    WithRelationProvider(provider).
    WithRelationProviders(map[reflect.Type]router.RelationMetadataProvider{
        reflect.TypeOf(User{}): userSpecificProvider,
    })

// Optional: trim or enrich relation metadata before it is published.
router.RegisterRelationFilter(func(t reflect.Type, desc *router.RelationDescriptor) *router.RelationDescriptor {
    if desc == nil {
        return nil
    }
    delete(desc.Tree.Children, "internalFlags")
    return desc
})

aggregator.AddProvider(controller)
doc := aggregator.GenerateOpenAPI()
  • Each schema with relation metadata exposes a vendor extension:
components:
  schemas:
    author:
      x-formgen-relations:
        includes:
          - books
          - books.publisher
        relations:
          - name: books.publisher
            filters:
              - field: country
                operator: eq
        tree:
          name: author
          fields: [id, name]
          children:
            books:
              name: books
              children:
                publisher:
                  name: publisher
  • Downstream packages (e.g., go-crud, go-formgen) can read the extension to drive include UIs, validation, and filter builders without duplicating repository logic.
Property Level Relationship Metadata (x-relationships, x-endpoint)
  • Relation fields live in SchemaMetadata.Properties, and SchemaMetadata.RelationAliases ties scalar foreign keys (for example author_id) to their richer object counterparts (author).
  • During OpenAPI generation the aggregator emits x-relationships and x-endpoint blocks for both representations, so UI builders understand cardinality, schema targets, and where to fetch options.
properties:
  author:
    type: object
    allOf:
      - $ref: '#/components/schemas/author'
    x-relationships:
      type: belongsTo
      target: '#/components/schemas/author'
      foreignKey: author_id
      cardinality: one
      sourceField: author_id
    x-endpoint:
      url: /api/authors
      method: GET
      labelField: full_name
      valueField: id
      params:
        select: id,full_name
        order: full_name asc
  author_id:
    type: string
    x-relationships:
      type: belongsTo
      target: '#/components/schemas/author'
      foreignKey: author_id
      cardinality: one
    x-endpoint:
      url: /api/authors
      method: GET
  • Use MetadataAggregator.WithUISchemaOptions to supply sensible defaults, override individual relations, or filter metadata before it reaches the final schema:
aggregator := router.NewMetadataAggregator().WithUISchemaOptions(router.UISchemaOptions{
    EndpointDefaults: func(resource *router.ResourceMetadata, relationName string, rel *router.RelationshipInfo) *router.EndpointHint {
        if relationName == "editor" {
            return &router.EndpointHint{URL: "/api/editors", Method: "GET", LabelField: "name", ValueField: "id"}
        }
        return nil
    },
    EndpointOverrides: map[string]map[string]*router.EndpointHint{
        "article": {
            "author": {URL: "/override/authors", Method: "POST"},
        },
    },
    RelationFilters: []router.RelationshipInfoFilter{
        func(resource *router.ResourceMetadata, relationName string, rel *router.RelationshipInfo) *router.RelationshipInfo {
            if relationName == "internal" {
                return nil // drop this relation entirely
            }
            return rel
        },
    },
})
  • Downstream consumers can now render choice widgets or nested editors without additional lookups; scalar fields carry the same metadata as their object companions so either representation can be used interchangeably.
Performance Considerations
  • Default configuration has minimal overhead and maintains backward compatibility
  • Enhanced metadata options increase processing time but provide richer information
  • Custom handlers are only called when relevant tags are present
  • Field filtering can improve performance by skipping unnecessary fields
Common Use Cases
  1. OpenAPI Schema Generation: Extract field types, validation rules, and relationships for API documentation
  2. Database Migration Tools: Analyze struct relationships and generate database schemas
  3. Form Generation: Create web forms based on struct validation tags
  4. Code Documentation: Auto generate documentation from struct comments and tags
  5. Data Validation: Extract validation rules for runtime validation
  6. API Client Generation: Generate client SDKs based on struct definitions
Supported Tags

The metadata extractor recognizes and processes the following struct tag types:

  • json: Field naming and serialization options
  • bun: Database ORM tags for relationships and constraints
  • validate: Validation rules and constraints
  • crud: Custom CRUD operation metadata
  • xml, yaml: Alternative serialization formats
  • form, query, param, header: HTTP parameter binding
  • db, gorm: Alternative database ORM tags
  • Custom tags via CustomTagHandlers

For complete examples and advanced usage patterns, see the test files in the repository.

License

MIT Goliatone

Documentation

Index

Constants

View Source
const (
	CookieSameSiteDisabled   = "disabled" // not in RFC, just control "SameSite" attribute will not be set.
	CookieSameSiteLaxMode    = "lax"
	CookieSameSiteStrictMode = "strict"
	CookieSameSiteNoneMode   = "none"
)
View Source
const (
	TAG_CRUD         = "crud"
	TAG_BUN          = "bun"
	TAG_JSON         = "json"
	TAG_KEY_RESOURCE = "resource"
)
View Source
const (
	HeaderAuthorization = "Authorization"
	HeaderContentType   = "Content-Type"
)
View Source
const (
	SSEClientVersion = WebSocketClientVersion
	SSEClientBuild   = WebSocketClientBuild
)
View Source
const (
	StatusContinue           = http.StatusContinue
	StatusSwitchingProtocols = http.StatusSwitchingProtocols
	StatusProcessing         = http.StatusProcessing
	StatusEarlyHints         = http.StatusEarlyHints

	StatusOK                   = http.StatusOK
	StatusCreated              = http.StatusCreated
	StatusAccepted             = http.StatusAccepted
	StatusNonAuthoritativeInfo = http.StatusNonAuthoritativeInfo
	StatusNoContent            = http.StatusNoContent
	StatusResetContent         = http.StatusResetContent
	StatusPartialContent       = http.StatusPartialContent
	StatusMultiStatus          = http.StatusMultiStatus
	StatusAlreadyReported      = http.StatusAlreadyReported
	StatusIMUsed               = http.StatusIMUsed

	StatusMultipleChoices   = http.StatusMultipleChoices
	StatusMovedPermanently  = http.StatusMovedPermanently
	StatusFound             = http.StatusFound
	StatusSeeOther          = http.StatusSeeOther
	StatusNotModified       = http.StatusNotModified
	StatusUseProxy          = http.StatusUseProxy
	StatusTemporaryRedirect = http.StatusTemporaryRedirect
	StatusPermanentRedirect = http.StatusPermanentRedirect

	StatusBadRequest                   = http.StatusBadRequest
	StatusUnauthorized                 = http.StatusUnauthorized
	StatusPaymentRequired              = http.StatusPaymentRequired
	StatusForbidden                    = http.StatusForbidden
	StatusNotFound                     = http.StatusNotFound
	StatusMethodNotAllowed             = http.StatusMethodNotAllowed
	StatusNotAcceptable                = http.StatusNotAcceptable
	StatusProxyAuthRequired            = http.StatusProxyAuthRequired
	StatusRequestTimeout               = http.StatusRequestTimeout
	StatusConflict                     = http.StatusConflict
	StatusGone                         = http.StatusGone
	StatusLengthRequired               = http.StatusLengthRequired
	StatusPreconditionFailed           = http.StatusPreconditionFailed
	StatusRequestEntityTooLarge        = http.StatusRequestEntityTooLarge
	StatusRequestURITooLong            = http.StatusRequestURITooLong
	StatusUnsupportedMediaType         = http.StatusUnsupportedMediaType
	StatusRequestedRangeNotSatisfiable = http.StatusRequestedRangeNotSatisfiable
	StatusExpectationFailed            = http.StatusExpectationFailed
	StatusTeapot                       = http.StatusTeapot
	StatusMisdirectedRequest           = http.StatusMisdirectedRequest
	StatusUnprocessableEntity          = http.StatusUnprocessableEntity
	StatusLocked                       = http.StatusLocked
	StatusFailedDependency             = http.StatusFailedDependency
	StatusTooEarly                     = http.StatusTooEarly
	StatusUpgradeRequired              = http.StatusUpgradeRequired
	StatusPreconditionRequired         = http.StatusPreconditionRequired
	StatusTooManyRequests              = http.StatusTooManyRequests
	StatusRequestHeaderFieldsTooLarge  = http.StatusRequestHeaderFieldsTooLarge
	StatusUnavailableForLegalReasons   = http.StatusUnavailableForLegalReasons

	StatusInternalServerError           = http.StatusInternalServerError
	StatusNotImplemented                = http.StatusNotImplemented
	StatusBadGateway                    = http.StatusBadGateway
	StatusServiceUnavailable            = http.StatusServiceUnavailable
	StatusGatewayTimeout                = http.StatusGatewayTimeout
	StatusHTTPVersionNotSupported       = http.StatusHTTPVersionNotSupported
	StatusVariantAlsoNegotiates         = http.StatusVariantAlsoNegotiates
	StatusInsufficientStorage           = http.StatusInsufficientStorage
	StatusLoopDetected                  = http.StatusLoopDetected
	StatusNotExtended                   = http.StatusNotExtended
	StatusNetworkAuthenticationRequired = http.StatusNetworkAuthenticationRequired
)
View Source
const (
	TextMessage   = 1
	BinaryMessage = 2
	CloseMessage  = 8
	PingMessage   = 9
	PongMessage   = 10
)

WebSocket message types (compatible with RFC 6455)

View Source
const (
	CloseNormalClosure           = 1000
	CloseGoingAway               = 1001
	CloseProtocolError           = 1002
	CloseUnsupportedData         = 1003
	CloseNoStatusReceived        = 1005
	CloseAbnormalClosure         = 1006
	CloseInvalidFramePayloadData = 1007
	ClosePolicyViolation         = 1008
	CloseMessageTooBig           = 1009
	CloseMandatoryExtension      = 1010
	CloseInternalServerErr       = 1011
	CloseServiceRestart          = 1012
	CloseTryAgainLater           = 1013
	CloseTLSHandshake            = 1015
)

WebSocket close codes (RFC 6455 compliant)

View Source
const (
	WebSocketKey        = "Sec-WebSocket-Key"
	WebSocketVersion    = "Sec-WebSocket-Version"
	WebSocketProtocol   = "Sec-WebSocket-Protocol"
	WebSocketExtensions = "Sec-WebSocket-Extensions"
	WebSocketAccept     = "Sec-WebSocket-Accept"
)

WebSocket headers

View Source
const (
	WebSocketClientVersion = "0.57.0"
	WebSocketClientBuild   = "production"
)

Version and build information

View Source
const ErrorHandlerConfigKey = "error_handler_config"
View Source
const (
	XRequestID = "X-Request-ID"
)

Variables

View Source
var (
	// ErrUnknownNamespace indicates the requested namespace key is not configured.
	ErrUnknownNamespace = errors.New("router: unknown namespace")
	// ErrUnknownRouteKey indicates the requested route key is not configured in the namespace.
	ErrUnknownRouteKey = errors.New("router: unknown route key")
)
View Source
var (
	// Connection errors
	ErrConnectionClosed = errors.New("websocket: connection closed")
	ErrConnectionLost   = errors.New("websocket: connection lost")

	// Message errors
	ErrMessageTooLarge = errors.New("websocket: message too large")
	ErrInvalidMessage  = errors.New("websocket: invalid message format")
	ErrEmptyMessage    = errors.New("websocket: empty message")
	ErrMessageTooLong  = errors.New("websocket: message too long")

	// Rate limiting
	ErrRateLimitExceeded = errors.New("websocket: rate limit exceeded")

	// Authentication
	ErrUnauthorized    = errors.New("websocket: unauthorized")
	ErrMissingUsername = errors.New("websocket: missing username")

	// Internal errors
	ErrInternalServer = errors.New("websocket: internal server error")
)

WebSocket error definitions

View Source
var (
	CloseNormalError          = WSError{Code: CloseNormalClosure, Reason: "normal closure"}
	CloseGoingAwayError       = WSError{Code: CloseGoingAway, Reason: "going away"}
	CloseProtocolErrorWS      = WSError{Code: CloseProtocolError, Reason: "protocol error"}
	CloseUnsupportedDataError = WSError{Code: CloseUnsupportedData, Reason: "unsupported data"}
	CloseNoStatusError        = WSError{Code: CloseNoStatusReceived, Reason: "no status received"}
	CloseAbnormalError        = WSError{Code: CloseAbnormalClosure, Reason: "abnormal closure"}
	CloseInvalidPayloadError  = WSError{Code: CloseInvalidFramePayloadData, Reason: "invalid frame payload data"}
	ClosePolicyViolationError = WSError{Code: ClosePolicyViolation, Reason: "policy violation"}
	CloseMessageTooBigError   = WSError{Code: CloseMessageTooBig, Reason: "message too big"}
	CloseMandatoryExtError    = WSError{Code: CloseMandatoryExtension, Reason: "mandatory extension"}
	CloseInternalServerError  = WSError{Code: CloseInternalServerErr, Reason: "internal server error"}
	CloseServiceRestartError  = WSError{Code: CloseServiceRestart, Reason: "service restart"}
	CloseTryAgainLaterError   = WSError{Code: CloseTryAgainLater, Reason: "try again later"}
	CloseTLSHandshakeError    = WSError{Code: CloseTLSHandshake, Reason: "TLS handshake"}
	CloseRateLimitExceeded    = WSError{Code: ClosePolicyViolation, Reason: "rate limit exceeded"}
)

Common WebSocket errors with close codes

View Source
var ErrOriginProtectionRejected = errors.New("origin protection rejected request")
View Source
var LoggerEnabled = false
View Source
var WSAuthConfigDefault = WSAuthConfig{
	ContextEnricher: defaultContextEnricher,
	OnAuthFailure:   defaultAuthFailureHandler,
	Logger:          &defaultLogger{},
}

WSAuthConfigDefault provides default configuration for WSAuth middleware

View Source
var WSLoggerConfigDefault = WSLoggerConfig{
	Logger: &defaultLogger{},
	Skip:   nil,
	Formatter: func(client WSClient, start, stop time.Time) string {
		return fmt.Sprintf("[WS] %s | %s | %v | %s",
			client.ID(),
			client.Conn().RemoteAddr(),
			stop.Sub(start),
			client.Conn().Path(),
		)
	},
}

WSLoggerConfigDefault provides default configuration for WSLogger middleware

View Source
var WSMetricsConfigDefault = WSMetricsConfig{
	Sink: &defaultMetricsSink{},
	Skip: nil,
}

WSMetricsConfigDefault provides default configuration for WSMetrics middleware

View Source
var WSRateLimitConfigDefault = WSRateLimitConfig{
	Store: NewWSInMemoryRateLimitStore(rate.Limit(10), 1),
	Skip:  nil,
	KeyFunc: func(client WSClient) string {
		return client.ID()
	},
	OnRateLimited: nil,
}

WSRateLimitConfigDefault provides default configuration for WSRateLimit middleware

View Source
var WSRecoverConfigDefault = WSRecoverConfig{
	Logger:           &defaultLogger{},
	Skip:             nil,
	StackSize:        4 << 10,
	EnableStackTrace: true,
}

WSRecoverConfigDefault provides default configuration for WSRecover middleware

Functions

func AbsFromCaller added in v0.40.0

func AbsFromCaller(rel string, skip ...int) string

AbsFromCaller resolves rel relative to the caller's source file. If rel is absolute, it is returned as-is. If runtime.Caller fails, filepath.Clean(rel) is returned instead.

Example:

assetsDir := router.AbsFromCaller("testdata/static")

func BroadcastJSON added in v0.6.0

func BroadcastJSON(connections []WebSocketContext, v any, maxSize int64) error

BroadcastJSON broadcasts a JSON message to multiple connections

func CompressMessage added in v0.6.0

func CompressMessage(data []byte, config CompressionConfig) ([]byte, bool, error)

CompressMessage compresses a message if it meets criteria

func ConstrainedPathParam added in v0.44.0

func ConstrainedPathParam(name, constraint string) string

ConstrainedPathParam returns a parameter segment with a constraint. Note: constraint syntax is Fiber-specific; httprouter treats it as part of the param name.

func DebugAssetPaths added in v0.2.0

func DebugAssetPaths(lgr Logger, dir fs.FS, labels ...string)

func DecompressMessage added in v0.6.0

func DecompressMessage(data []byte) ([]byte, error)

DecompressMessage decompresses a message

func DefaultFiberErrorHandler added in v0.26.0

func DefaultFiberErrorHandler(cfg FiberErrorHandlerConfig) func(c *fiber.Ctx, err error) error

func DefaultFiberOptions

func DefaultFiberOptions(app *fiber.App) *fiber.App

func DefaultHTTPErrorHandler added in v0.39.0

func DefaultHTTPErrorHandler(cfg HTTPErrorHandlerConfig) func(c Context, err error) error

func DefaultHTTPRouterOptions

func DefaultHTTPRouterOptions(router *httprouter.Router) *httprouter.Router

func DefaultViewEngine added in v0.1.0

func DefaultViewEngine(cfg ViewConfigProvider, lgrs ...Logger) (fiber.Views, error)

func DirExists added in v0.2.0

func DirExists(path string, afs ...fs.FS) bool

func EnhanceWSHub added in v0.6.0

func EnhanceWSHub(hub *WSHub)

EnhanceWSHub adds room management capabilities to an existing hub

func ErrWebSocketMessageTooBig added in v0.6.0

func ErrWebSocketMessageTooBig(size int64, maxSize int64) error

ErrWebSocketMessageTooBig creates an error for oversized messages

func ErrWebSocketUpgradeFailed added in v0.6.0

func ErrWebSocketUpgradeFailed(cause error) error

ErrWebSocketUpgradeFailed creates an error for WebSocket upgrade failures

func FiberWebSocketHandler added in v0.6.0

func FiberWebSocketHandler(config WebSocketConfig, handler func(WebSocketContext) error) fiber.Handler

FiberWebSocketHandler creates a Fiber-specific WebSocket handler using contrib/websocket

func GetContextValue added in v0.0.2

func GetContextValue[T any](c Context, key string, def T) T

GetContextValue functions for type assertion

func GetResourceName added in v0.5.0

func GetResourceName(typ reflect.Type) (string, string)

GetResourceName returns the singular and plural resource names for type T. It first checks for a 'crud:"resource:..."' tag on any embedded fields. If found, it uses the specified resource name. Otherwise, it derives the name from the type's name.

func GetResourceTitle added in v0.5.0

func GetResourceTitle(typ reflect.Type) (string, string)

func GetUpgradeDataWithDefault added in v0.8.0

func GetUpgradeDataWithDefault(ws WebSocketContext, key string, defaultValue any) any

GetUpgradeDataWithDefault is a convenience function for WebSocket contexts

func HTTPRouterWebSocketHandler added in v0.6.0

func HTTPRouterWebSocketHandler(config WebSocketConfig, handler func(WebSocketContext) error, views Views) httprouter.Handle

HTTPRouterWebSocketHandler creates an HTTPRouter-specific WebSocket handler

func InitializeViewEngine added in v0.1.0

func InitializeViewEngine(opts ViewConfigProvider, lgrs ...Logger) (fiber.Views, error)

func ListRegisteredAdapters added in v0.6.0

func ListRegisteredAdapters() []string

ListRegisteredAdapters returns all registered adapter names

func LogError added in v0.0.2

func LogError(logger Logger, err *errors.Error, c Context)

LogError logs the error with context information

func MergeLocalsWithViewData added in v0.28.0

func MergeLocalsWithViewData(ctx *fiber.Ctx, logger Logger, strategy RenderMergeStrategy, bind any) (map[string]any, error)

MergeLocalsWithViewData combines a render bind value with Fiber locals using the provided strategy.

func MustSubFS added in v0.40.0

func MustSubFS(base fs.FS, subdir string) fs.FS

MustSubFS is a convenience wrapper around SubFS that panics on error.

func NewBadRequestError added in v0.0.2

func NewBadRequestError(message string, metas ...map[string]any) *errors.Error

NewBadRequestError for generic bad requests outside of validation context

func NewConflictError added in v0.0.2

func NewConflictError(message string, metas ...map[string]any) *errors.Error

NewConflictError for requests that could not be completed due to a conflict

func NewFiberWebSocketContext added in v0.6.0

func NewFiberWebSocketContext(c *fiber.Ctx, config WebSocketConfig, logger Logger) (*fiberWebSocketContext, error)

NewFiberWebSocketContext creates a new Fiber WebSocket context

func NewForbiddenError added in v0.0.2

func NewForbiddenError(message string, metas ...map[string]any) *errors.Error

func NewHTTPRouterWebSocketContext added in v0.6.0

func NewHTTPRouterWebSocketContext(w http.ResponseWriter, r *http.Request, ps httprouter.Params, config WebSocketConfig, views Views) (*httpRouterWebSocketContext, error)

NewHTTPRouterWebSocketContext creates a new HTTPRouter WebSocket context

func NewHandlerError added in v0.2.4

func NewHandlerError(err error, message string, metas ...map[string]any) *errors.Error

func NewInternalError added in v0.0.2

func NewInternalError(err error, message string, metas ...map[string]any) *errors.Error

func NewMethodNotAllowedError added in v0.0.2

func NewMethodNotAllowedError(message string, metas ...map[string]any) *errors.Error

NewMethodNotAllowedError for requests that use an unallowed HTTP method

func NewMiddlewareError added in v0.2.4

func NewMiddlewareError(err error, message string, metas ...map[string]any) *errors.Error

func NewNotFoundError added in v0.0.2

func NewNotFoundError(message string, metas ...map[string]any) *errors.Error

func NewRoutingError added in v0.2.4

func NewRoutingError(message string, metas ...map[string]any) *errors.Error

func NewTooManyRequestsError added in v0.0.2

func NewTooManyRequestsError(message string, metas ...map[string]any) *errors.Error

NewTooManyRequestsError for rate-limiting scenarios

func NewUnauthorizedError added in v0.0.2

func NewUnauthorizedError(message string, metas ...map[string]any) *errors.Error

func NewValidationError added in v0.0.2

func NewValidationError(message string, validationErrs []errors.FieldError, metas ...map[string]any) *errors.Error

NewValidationError

func NewWSHandler added in v0.6.0

func NewWSHandler(handler func(context.Context, WSClient) error) func(Context) error

NewWSHandler creates a simple WebSocket handler with minimal configuration

func NormalizeCookieSameSite added in v0.55.0

func NormalizeCookieSameSite(value string) string

func NormalizePath added in v0.2.0

func NormalizePath(path string) string

func ParseEventNamespace added in v0.6.0

func ParseEventNamespace(eventType string) (namespace, event string)

ParseEventNamespace extracts namespace from event type (e.g., "chat:message" -> "chat", "message")

func PathParam added in v0.44.0

func PathParam(name string) string

PathParam returns a parameter segment (e.g., ":id").

func PrepareErrorResponse added in v0.0.2

func PrepareErrorResponse(err *errors.Error, config ErrorHandlerConfig) errors.ErrorResponse

func ReadJSONSafe added in v0.6.0

func ReadJSONSafe(ctx WebSocketContext, v any, maxSize int64) error

ReadJSONSafe reads a JSON message with size validation

func RegisterFiberWebSocketFactory added in v0.6.0

func RegisterFiberWebSocketFactory(logger Logger)

RegisterFiberWebSocketFactory registers the Fiber WebSocket factory globally

func RegisterGlobalWebSocketFactory added in v0.6.0

func RegisterGlobalWebSocketFactory(adapterName string, factory WebSocketContextFactory)

RegisterGlobalWebSocketFactory registers a factory globally

func RegisterHTTPRouterWebSocketFactory added in v0.6.0

func RegisterHTTPRouterWebSocketFactory(views Views)

RegisterHTTPRouterWebSocketFactory registers the HTTPRouter WebSocket factory globally

func RegisterRelationFilter added in v0.22.0

func RegisterRelationFilter(filter RelationFilterFunc)

RegisterRelationFilter appends a filter function executed in registration order.

func RegisterSSEClientRoutesManual added in v0.54.0

func RegisterSSEClientRoutesManual() map[string]HandlerFunc

RegisterSSEClientRoutesManual provides named handlers for manual registration.

func RegisterSSEHandlers added in v0.54.0

func RegisterSSEHandlers[T any](app Router[T], cfgs ...SSEClientHandlerConfig)

RegisterSSEHandlers registers the embedded SSE client assets on the router.

func RegisterWSHandlers added in v0.8.0

func RegisterWSHandlers[T any](app Router[T], cfgs ...WSClientHandlerConfig)

Convenience handler functions for common patterns

func RegisterWebSocketClientRoutesManual added in v0.8.0

func RegisterWebSocketClientRoutesManual() map[string]HandlerFunc

RegisterWebSocketClientRoutesManual provides a helper for manual registration

func RegisterWebSocketFactory added in v0.6.0

func RegisterWebSocketFactory(adapterName string, factory WebSocketContextFactory)

RegisterWebSocketFactory registers a WebSocket factory for an adapter

func ResolvePath added in v0.2.0

func ResolvePath(base, subPath string) string

func ResolveRedirectBackTarget added in v0.55.0

func ResolveRedirectBackTarget(c Context, fallback string) string

func RouteNameFromContext added in v0.9.0

func RouteNameFromContext(ctx context.Context) (string, bool)

func RouteParamsFromContext added in v0.9.0

func RouteParamsFromContext(ctx context.Context) (map[string]string, bool)

func SSEClientInfo added in v0.54.0

func SSEClientInfo() map[string]any

SSEClientInfo returns metadata for the embedded SSE client assets.

func SanitizeRedirectTarget added in v0.55.0

func SanitizeRedirectTarget(raw, scheme, host string) (string, bool)

func SerializeAsContext added in v0.1.0

func SerializeAsContext(m any) (map[string]any, error)

SerializeAsContext will return any object as a PageContext instance

func ServeOpenAPI added in v0.0.2

func ServeOpenAPI[T any](router Router[T], renderer OpenApiMetaGenerator, opts ...OpenAPIOption)

func StatusText added in v0.1.0

func StatusText(code int) string

func SubFS added in v0.40.0

func SubFS(base fs.FS, subdir string) (fs.FS, error)

SubFS scopes base to subdir if present, otherwise returns base. It mirrors autoSubFS behavior by normalizing paths and ignoring missing subdirectories.

Example:

assetsFS, _ := router.SubFS(embeddedAssets, "assets")

func ToKebabCase added in v0.5.0

func ToKebabCase(s string) string

func ValidateConfig added in v0.2.0

func ValidateConfig(cfg ViewConfigProvider) error

func ValidateCookie added in v0.55.0

func ValidateCookie(cookie Cookie) error

func ValidateOwnedRouteSets added in v0.53.0

func ValidateOwnedRouteSets(routeSets []OwnedRouteSet, policy RouteOwnershipPolicy) []error

func ValidateRouteDefinitions added in v0.44.0

func ValidateRouteDefinitions(routes []*RouteDefinition) []error

ValidateRouteDefinitions checks for conflicting or ambiguous routes.

func ValidateRouteDefinitionsWithOptions added in v0.47.0

func ValidateRouteDefinitionsWithOptions(routes []*RouteDefinition, opts RouteValidationOptions) []error

ValidateRouteDefinitionsWithOptions checks route conflicts using the provided path conflict mode.

func ValidateWebSocketSecurity added in v0.6.0

func ValidateWebSocketSecurity(c Context, policy WebSocketSecurityPolicy) error

ValidateWebSocketSecurity performs comprehensive security validation

func WSTokenIDFromContext added in v0.45.0

func WSTokenIDFromContext(ctx context.Context) (string, bool)

WSTokenIDFromContext retrieves token ID from auth claims when available.

func WebSocketClientInfo added in v0.8.0

func WebSocketClientInfo() map[string]any

WebSocketClientInfo returns information about the embedded client

func WithHTTPRouterConflictPolicy added in v0.41.0

func WithHTTPRouterConflictPolicy(policy HTTPRouterConflictPolicy) func(*httprouter.Router) *httprouter.Router

WithHTTPRouterConflictPolicy configures conflict handling for NewHTTPServer.

func WithHTTPRouterNamedRoutePolicy added in v0.53.0

func WithHTTPRouterNamedRoutePolicy(policy NamedRouteCollisionPolicy) func(*httprouter.Router) *httprouter.Router

WithHTTPRouterNamedRoutePolicy configures named-route collision handling for NewHTTPServer.

func WithHTTPRouterPathConflictMode added in v0.47.0

func WithHTTPRouterPathConflictMode(mode PathConflictMode) func(*httprouter.Router) *httprouter.Router

WithHTTPRouterPathConflictMode configures path conflict handling mode for NewHTTPServer. HTTPRouter currently only supports strict mode.

func WithHTTPServerStrictRoutes added in v0.44.0

func WithHTTPServerStrictRoutes(strict bool) func(*httprouter.Router) *httprouter.Router

WithHTTPServerStrictRoutes enables route validation during Init.

func WithRouteName added in v0.9.0

func WithRouteName(ctx context.Context, name string) context.Context

Helper functions for type-safe context operations

func WithRouteParams added in v0.9.0

func WithRouteParams(ctx context.Context, params map[string]string) context.Context

func WriteBinaryMessage added in v0.6.0

func WriteBinaryMessage(conn *websocket.Conn, data []byte, timeout time.Duration) error

WriteBinaryMessage is a helper to write binary messages

func WriteJSONMessage added in v0.6.0

func WriteJSONMessage(conn *websocket.Conn, v any, timeout time.Duration) error

WriteJSONMessage is a helper to write JSON messages

func WriteJSONSafe added in v0.6.0

func WriteJSONSafe(ctx WebSocketContext, v any, maxSize int64) error

WriteJSONSafe writes a JSON message with size validation

func WriteTextMessage added in v0.6.0

func WriteTextMessage(conn *websocket.Conn, message string, timeout time.Duration) error

WriteTextMessage is a helper to write text messages

Types

type AckBatcher added in v0.6.0

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

AckBatcher batches acknowledgments for efficiency

func NewAckBatcher added in v0.6.0

func NewAckBatcher(maxSize int, interval time.Duration, flushFunc func([]*EventAck)) *AckBatcher

NewAckBatcher creates a new acknowledgment batcher

func (*AckBatcher) Add added in v0.6.0

func (b *AckBatcher) Add(ack *EventAck)

Add adds an acknowledgment to the batch

func (*AckBatcher) Close added in v0.6.0

func (b *AckBatcher) Close()

Close flushes any remaining acknowledgments

type AckHandler added in v0.6.0

type AckHandler func(ctx context.Context, ack *EventAck) error

AckHandler handles acknowledgments for events

type AckManager added in v0.6.0

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

AckManager manages event acknowledgments

func NewAckManager added in v0.6.0

func NewAckManager(defaultTimeout time.Duration) *AckManager

NewAckManager creates a new acknowledgment manager

func (*AckManager) CancelAck added in v0.6.0

func (m *AckManager) CancelAck(ackID string)

CancelAck cancels a pending acknowledgment

func (*AckManager) HandleAck added in v0.6.0

func (m *AckManager) HandleAck(ack *EventAck) error

HandleAck processes an incoming acknowledgment

func (*AckManager) PendingCount added in v0.6.0

func (m *AckManager) PendingCount() int

PendingCount returns the number of pending acknowledgments

func (*AckManager) SendWithAck added in v0.6.0

func (m *AckManager) SendWithAck(ctx context.Context, client WSClient, event *EventMessage, timeout time.Duration) (*EventAck, error)

SendWithAck sends an event and waits for acknowledgment

func (*AckManager) SendWithCallback added in v0.6.0

func (m *AckManager) SendWithCallback(ctx context.Context, client WSClient, event *EventMessage, callback AckHandler, timeout time.Duration) error

SendWithCallback sends an event and calls callback on acknowledgment

type BaseRouter added in v0.0.3

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

Common fields for both FiberRouter and HTTPRouter

func (*BaseRouter) GetRoute added in v0.1.0

func (br *BaseRouter) GetRoute(name string) *RouteDefinition

func (*BaseRouter) PrintRoutes added in v0.0.3

func (br *BaseRouter) PrintRoutes()

func (*BaseRouter) RouteNameFromPath added in v0.9.0

func (br *BaseRouter) RouteNameFromPath(method string, pathPattern string) (string, bool)

func (*BaseRouter) Routes added in v0.0.3

func (br *BaseRouter) Routes() []RouteDefinition

func (*BaseRouter) ValidateRoutes added in v0.44.0

func (br *BaseRouter) ValidateRoutes() []error

func (*BaseRouter) WithLogger added in v0.2.1

func (br *BaseRouter) WithLogger(logger Logger) *BaseRouter

type BaseWebSocketContextFactory added in v0.6.0

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

BaseWebSocketContextFactory provides common functionality for all WebSocket context factories

func (*BaseWebSocketContextFactory) AdapterName added in v0.6.0

func (f *BaseWebSocketContextFactory) AdapterName() string

AdapterName returns the name of the adapter this factory supports

func (*BaseWebSocketContextFactory) SupportedContextTypes added in v0.13.0

func (f *BaseWebSocketContextFactory) SupportedContextTypes() []string

SupportedContextTypes returns the context type patterns this factory supports Default implementation returns the adapter name for backward compatibility

func (*BaseWebSocketContextFactory) SupportsWebSocket added in v0.6.0

func (f *BaseWebSocketContextFactory) SupportsWebSocket() bool

SupportsWebSocket always returns true for WebSocket context factories

type BatchedAck added in v0.6.0

type BatchedAck struct {
	IDs       []string  `json:"ids"`
	Success   bool      `json:"success"`
	Results   any       `json:"results,omitempty"`
	Error     string    `json:"error,omitempty"`
	Timestamp time.Time `json:"timestamp"`
}

BatchedAck allows acknowledging multiple events at once

type BinaryHandler added in v0.6.0

type BinaryHandler func(ctx context.Context, client WSClient, msg *BinaryPayload) error

BinaryHandler handles binary messages

type BinaryMessageCodec added in v0.6.0

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

BinaryMessageCodec encodes/decodes binary messages

func NewBinaryMessageCodec added in v0.6.0

func NewBinaryMessageCodec(maxSize int64) *BinaryMessageCodec

NewBinaryMessageCodec creates a new binary message codec

func (*BinaryMessageCodec) Decode added in v0.6.0

func (c *BinaryMessageCodec) Decode(data []byte) (*BinaryPayload, error)

Decode decodes a binary message

func (*BinaryMessageCodec) Encode added in v0.6.0

func (c *BinaryMessageCodec) Encode(msg *BinaryPayload) ([]byte, error)

Encode encodes a binary message

type BinaryPayload added in v0.6.0

type BinaryPayload struct {
	Type      string         `json:"type"`
	ID        string         `json:"id"`
	Data      []byte         `json:"-"`
	Metadata  map[string]any `json:"metadata,omitempty"`
	Timestamp time.Time      `json:"timestamp"`
}

BinaryPayload represents a binary WebSocket message with metadata

type ClientSession added in v0.6.0

type ClientSession struct {
	ID             string
	ClientID       string
	State          map[string]any
	LastSeen       time.Time
	DisconnectTime time.Time
	ReconnectToken string
	Subscriptions  []string // Room/channel subscriptions
	MessageQueue   *MessageQueue
	// contains filtered or unexported fields
}

ClientSession represents a client's session state

type CompressedMessage added in v0.6.0

type CompressedMessage struct {
	Compressed bool   `json:"compressed"`
	Algorithm  string `json:"algorithm,omitempty"`
	Data       []byte `json:"data"`
}

CompressedMessage wraps a message with compression metadata

type CompressionConfig added in v0.6.0

type CompressionConfig struct {
	Enabled         bool
	Level           int  // Compression level (0-9)
	Threshold       int  // Minimum message size to compress (bytes)
	ContextTakeover bool // Allow context takeover
}

CompressionConfig configures WebSocket compression

func DefaultCompressionConfig added in v0.6.0

func DefaultCompressionConfig() CompressionConfig

DefaultCompressionConfig returns default compression configuration

type CompressionManager added in v0.6.0

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

CompressionManager handles message compression

func NewCompressionManager added in v0.6.0

func NewCompressionManager(config CompressionConfig) *CompressionManager

NewCompressionManager creates a new compression manager

func (*CompressionManager) GetConfig added in v0.6.0

func (m *CompressionManager) GetConfig() CompressionConfig

GetConfig returns the current compression configuration

func (*CompressionManager) ShouldCompress added in v0.6.0

func (m *CompressionManager) ShouldCompress(data []byte) bool

ShouldCompress determines if a message should be compressed

func (*CompressionManager) UpdateConfig added in v0.6.0

func (m *CompressionManager) UpdateConfig(config CompressionConfig)

UpdateConfig updates the compression configuration

type ConnectionPool added in v0.6.0

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

ConnectionPool manages a pool of WebSocket connections

func NewConnectionPool added in v0.6.0

func NewConnectionPool(maxSize int) *ConnectionPool

NewConnectionPool creates a new connection pool

func (*ConnectionPool) Add added in v0.6.0

Add adds a connection to the pool

func (*ConnectionPool) Broadcast added in v0.6.0

func (p *ConnectionPool) Broadcast(messageType int, data []byte)

Broadcast sends a message to all connections

func (*ConnectionPool) CloseAll added in v0.6.0

func (p *ConnectionPool) CloseAll()

CloseAll closes all connections

func (*ConnectionPool) Get added in v0.6.0

Get retrieves a connection by ID

func (*ConnectionPool) GetAll added in v0.6.0

func (p *ConnectionPool) GetAll() []WebSocketContext

GetAll returns all connections

func (*ConnectionPool) Remove added in v0.6.0

func (p *ConnectionPool) Remove(id string)

Remove removes a connection from the pool

type Context

type Context interface {
	RequestContext
	ResponseWriter
	ContextStore
	// Body parsing
	Bind(v any) error // TODO: Myabe rename to ParseBody

	// Context methods
	Context() context.Context
	SetContext(context.Context)
	Next() error

	// Route context methods
	RouteName() string
	RouteParams() map[string]string
}

Context represents a generic HTTP context

func NewFiberContext

func NewFiberContext(c *fiber.Ctx, logger Logger) Context

func NewHTTPRouterContext

func NewHTTPRouterContext(w http.ResponseWriter, r *http.Request, ps httprouter.Params, views Views) Context

type ContextStore added in v0.0.2

type ContextStore interface {
	Set(key string, value any)
	Get(key string, def any) any
	GetString(key string, def string) string
	GetInt(key string, def int) int
	GetBool(key string, def bool) bool
}

ContextStore is a request scoped, in-memoroy store to pass data between middleware/handlers in the same request in a fremework agnostic way. If you need persistence between requests use Store e.g. for authentication middleware.

func NewContextStore added in v0.0.2

func NewContextStore() ContextStore
type Cookie struct {
	Name        string    `json:"name"`
	Value       string    `json:"value"`
	Path        string    `json:"path"`
	Domain      string    `json:"domain"`
	MaxAge      int       `json:"max_age"`
	Expires     time.Time `json:"expires"`
	Secure      bool      `json:"secure"`
	HTTPOnly    bool      `json:"http_only"`
	SameSite    string    `json:"same_site"`
	SessionOnly bool      `json:"session_only"`
}

Cookie data for c.Cookie

func EmbeddedThirdPartySessionCookie added in v0.55.0

func EmbeddedThirdPartySessionCookie(name, value string) Cookie

func FirstPartySessionCookie added in v0.55.0

func FirstPartySessionCookie(name, value string) Cookie

type CustomUpgrader added in v0.6.0

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

CustomUpgrader wraps a WebSocket upgrader with custom logic

func NewCustomUpgrader added in v0.6.0

func NewCustomUpgrader(config CustomUpgraderConfig) *CustomUpgrader

NewCustomUpgrader creates a new custom upgrader

func (*CustomUpgrader) UpdateConfig added in v0.6.0

func (u *CustomUpgrader) UpdateConfig(config CustomUpgraderConfig)

UpdateConfig updates the upgrader configuration

func (*CustomUpgrader) Upgrade added in v0.6.0

func (u *CustomUpgrader) Upgrade(ctx Context) (WebSocketContext, error)

Upgrade performs a custom WebSocket upgrade

type CustomUpgraderConfig added in v0.6.0

type CustomUpgraderConfig struct {
	// Core upgrader settings
	ReadBufferSize   int
	WriteBufferSize  int
	HandshakeTimeout time.Duration

	// Custom settings
	EnableCompression bool
	CompressionLevel  int
	Subprotocols      []string

	// Hooks
	BeforeUpgrade func(ctx Context) error
	AfterUpgrade  func(ctx WebSocketContext) error

	// Custom validation
	ValidateHeaders func(headers map[string][]string) error
	ValidateOrigin  func(origin string) bool

	// Error handling
	ErrorHandler func(ctx Context, err error) error
}

CustomUpgraderConfig allows custom upgrader configuration

type DeadlineManager added in v0.6.0

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

DeadlineManager manages connection deadlines and health checks

func NewDeadlineManager added in v0.6.0

func NewDeadlineManager(ctx WebSocketContext, config WebSocketConfig) *DeadlineManager

NewDeadlineManager creates a new deadline manager

func (*DeadlineManager) HealthCheck added in v0.6.0

func (d *DeadlineManager) HealthCheck() error

HealthCheck performs a health check on the connection

func (*DeadlineManager) Start added in v0.6.0

func (d *DeadlineManager) Start()

Start starts the deadline management

func (*DeadlineManager) Stop added in v0.6.0

func (d *DeadlineManager) Stop()

Stop stops the deadline management

type DefaultRelationProvider added in v0.22.0

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

DefaultRelationProvider reflects Bun CRUD tags to build relation metadata.

func NewDefaultRelationProvider added in v0.22.0

func NewDefaultRelationProvider() *DefaultRelationProvider

NewDefaultRelationProvider constructs a provider using native field extraction.

func (*DefaultRelationProvider) BuildRelationDescriptor added in v0.22.0

func (p *DefaultRelationProvider) BuildRelationDescriptor(resourceType reflect.Type) (*RelationDescriptor, error)

BuildRelationDescriptor implements RelationMetadataProvider.

type DownloadPayload added in v0.41.0

type DownloadPayload struct {
	ContentType    string
	Filename       string
	ExportID       string
	Size           int64
	MaxBufferBytes int64
	Reader         io.Reader
	Bytes          []byte
}

DownloadPayload describes a file download response.

type DownloadResponder added in v0.41.0

type DownloadResponder interface {
	WriteDownload(ctx context.Context, payload DownloadPayload) error
	WriteStream(ctx context.Context, contentType string, r io.Reader, opts ...StreamOption) error
}

DownloadResponder provides streaming download helpers.

func NewDownloadResponder added in v0.41.0

func NewDownloadResponder(ctx Context) DownloadResponder

NewDownloadResponder returns a download responder bound to the given context.

type EndpointDefaultFunc added in v0.23.0

type EndpointDefaultFunc func(resource *ResourceMetadata, relationName string, rel *RelationshipInfo) *EndpointHint

EndpointDefaultFunc derives default endpoint hints when tags are absent.

type EndpointHint added in v0.23.0

type EndpointHint struct {
	URL           string            `json:"url,omitempty"`
	Method        string            `json:"method,omitempty"`
	LabelField    string            `json:"labelField,omitempty"`
	ValueField    string            `json:"valueField,omitempty"`
	Params        map[string]string `json:"params,omitempty"`
	DynamicParams map[string]string `json:"dynamicParams,omitempty"`
	Mode          string            `json:"mode,omitempty"`
	SearchParam   string            `json:"searchParam,omitempty"`
	SubmitAs      string            `json:"submitAs,omitempty"`
}

EndpointHint provides UI-focused guidance for retrieving relation options.

type ErrorHandler added in v0.1.0

type ErrorHandler = func(Context, error) error

type ErrorHandlerConfig added in v0.0.2

type ErrorHandlerConfig struct {
	// Include stack traces in non-production environments
	IncludeStack bool
	// Custom error mapping functions
	ErrorMappers []errors.ErrorMapper
	// Logger interface for error logging
	Logger Logger
	// Environment (development, production, etc.)
	Environment string
	// Function to extract request ID from context
	GetRequestID func(c Context) string
}

ErrorHandlerConfig allows customization of error handling behavior

func DefaultErrorHandlerConfig added in v0.0.2

func DefaultErrorHandlerConfig() ErrorHandlerConfig

DefaultErrorHandlerConfig provides sensible defaults

type ErrorHandlerOption added in v0.0.2

type ErrorHandlerOption func(*ErrorHandlerConfig)

ErrorHandlerOption defines a function that can modify ErrorHandlerConfig

func WithEnvironment added in v0.0.2

func WithEnvironment(env string) ErrorHandlerOption

WithEnvironment sets the environment for error handling

func WithErrorMapper added in v0.0.2

func WithErrorMapper(mapper errors.ErrorMapper) ErrorHandlerOption

WithErrorMapper adds additional error mappers

func WithLogger added in v0.0.2

func WithLogger(logger Logger) ErrorHandlerOption

WithLogger sets the logger for error handling

func WithStackTrace added in v0.0.2

func WithStackTrace(include bool) ErrorHandlerOption

WithStackTrace enables or disables stack traces

type EventAck added in v0.6.0

type EventAck struct {
	ID        string    `json:"id"`
	Success   bool      `json:"success"`
	Data      any       `json:"data,omitempty"`
	Error     string    `json:"error,omitempty"`
	Timestamp time.Time `json:"timestamp"`
}

EventAck represents an event acknowledgment

func EmitWithAck added in v0.6.0

func EmitWithAck(ctx context.Context, client WSClient, eventType string, data any, timeout time.Duration) (*EventAck, error)

EmitWithAck sends an event and waits for acknowledgment

type EventBatcher added in v0.6.0

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

EventBatcher batches events for efficient processing

func NewEventBatcher added in v0.6.0

func NewEventBatcher(maxSize int, interval time.Duration, processor func([]*EventMessage)) *EventBatcher

NewEventBatcher creates a new event batcher

func (*EventBatcher) Add added in v0.6.0

func (b *EventBatcher) Add(event *EventMessage)

Add adds an event to the batch

func (*EventBatcher) Close added in v0.6.0

func (b *EventBatcher) Close()

Close flushes any remaining events

type EventHandler added in v0.6.0

type EventHandler func(ctx context.Context, client WSClient, data any) error

EventHandler handles typed events with context and error support

type EventHistory added in v0.6.0

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

EventHistory stores event history for replay

func NewEventHistory added in v0.6.0

func NewEventHistory(maxSize int, ttl time.Duration) *EventHistory

NewEventHistory creates a new event history

func (*EventHistory) Add added in v0.6.0

func (h *EventHistory) Add(event *EventMessage)

Add adds an event to history

func (*EventHistory) Clear added in v0.6.0

func (h *EventHistory) Clear()

Clear clears all history

func (*EventHistory) Get added in v0.6.0

func (h *EventHistory) Get(filter EventHistoryFilter) []*EventMessage

Get retrieves events from history based on filter

func (*EventHistory) Replay added in v0.6.0

func (h *EventHistory) Replay(client WSClient, filter EventHistoryFilter) error

Replay replays events to a client

func (*EventHistory) Size added in v0.6.0

func (h *EventHistory) Size() int

Size returns the number of events in history

type EventHistoryFilter added in v0.6.0

type EventHistoryFilter struct {
	// Filter by event type
	Type string

	// Filter by namespace
	Namespace string

	// Filter by client ID
	ClientID string

	// Filter by time range
	Since  *time.Time
	Before *time.Time

	// Maximum number of events to return
	Limit int

	// Offset for pagination
	Offset int
}

EventHistoryFilter filters events in history

type EventMessage added in v0.6.0

type EventMessage struct {
	ID        string         `json:"id,omitempty"`
	Type      string         `json:"type"`
	Namespace string         `json:"namespace,omitempty"`
	Data      any            `json:"data,omitempty"`
	Metadata  map[string]any `json:"metadata,omitempty"`
	Timestamp time.Time      `json:"timestamp"`
	AckID     string         `json:"ack_id,omitempty"`
}

EventMessage represents a structured event message

func RequestResponse added in v0.6.0

func RequestResponse(ctx context.Context, client WSClient, request *EventMessage, timeout time.Duration) (*EventMessage, error)

RequestResponse implements request-response pattern using acknowledgments

type EventMiddleware added in v0.6.0

type EventMiddleware func(ctx context.Context, client WSClient, event *EventMessage, next EventMiddlewareNext) error

EventMiddleware processes events before they reach handlers

func AckMiddleware added in v0.6.0

func AckMiddleware(ackManager *AckManager) EventMiddleware

AckMiddleware creates middleware that handles acknowledgments

func AuthorizationMiddleware added in v0.6.0

func AuthorizationMiddleware(authFunc func(context.Context, WSClient, *EventMessage) error) EventMiddleware

AuthorizationMiddleware checks event permissions

func LoggingMiddleware added in v0.6.0

func LoggingMiddleware() EventMiddleware

LoggingMiddleware logs all events

func RateLimitMiddleware added in v0.6.0

func RateLimitMiddleware(eventsPerSecond int) EventMiddleware

RateLimitMiddleware limits events per client

func ThrottleMiddleware added in v0.6.0

func ThrottleMiddleware(throttler *EventThrottler) EventMiddleware

ThrottleMiddleware creates middleware that throttles events

func TransformMiddleware added in v0.6.0

func TransformMiddleware(transformer func(*EventMessage) error) EventMiddleware

TransformMiddleware transforms event data

func ValidationMiddleware added in v0.6.0

func ValidationMiddleware(schemas map[string]any) EventMiddleware

ValidationMiddleware validates event data against schemas

type EventMiddlewareNext added in v0.6.0

type EventMiddlewareNext func(ctx context.Context, client WSClient, event *EventMessage) error

EventMiddlewareNext is the next function in the middleware chain

type EventNamespace added in v0.6.0

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

EventNamespace represents an isolated event space

func (*EventNamespace) Emit added in v0.6.0

func (ns *EventNamespace) Emit(ctx context.Context, event *EventMessage) error

Emit sends an event to all clients in this namespace

func (*EventNamespace) Join added in v0.6.0

func (ns *EventNamespace) Join(ctx context.Context, client WSClient) error

Join adds a client to this namespace

func (*EventNamespace) Leave added in v0.6.0

func (ns *EventNamespace) Leave(client WSClient)

Leave removes a client from this namespace

func (*EventNamespace) On added in v0.6.0

func (ns *EventNamespace) On(eventType string, handler TypedEventHandler) error

On registers an event handler in this namespace

func (*EventNamespace) SetAuth added in v0.6.0

func (ns *EventNamespace) SetAuth(authFunc NamespaceAuthFunc)

SetAuth sets the authorization function for this namespace

func (*EventNamespace) Use added in v0.6.0

func (ns *EventNamespace) Use(middleware EventMiddleware)

Use adds middleware to this namespace

type EventRouter added in v0.6.0

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

EventRouter manages event routing with namespaces

func NewEventRouter added in v0.6.0

func NewEventRouter(config EventRouterConfig) *EventRouter

NewEventRouter creates a new event router

func (*EventRouter) GetHistory added in v0.6.0

func (r *EventRouter) GetHistory(filter EventHistoryFilter) []*EventMessage

GetHistory returns event history

func (*EventRouter) Namespace added in v0.6.0

func (r *EventRouter) Namespace(name string) *EventNamespace

Namespace returns or creates a namespace

func (*EventRouter) On added in v0.6.0

func (r *EventRouter) On(eventType string, handler TypedEventHandler) error

On registers a global event handler

func (*EventRouter) RouteEvent added in v0.6.0

func (r *EventRouter) RouteEvent(ctx context.Context, client WSClient, event *EventMessage) error

RouteEvent routes an event through the system

func (*EventRouter) Use added in v0.6.0

func (r *EventRouter) Use(middleware EventMiddleware)

Use adds middleware to the global chain

type EventRouterConfig added in v0.6.0

type EventRouterConfig struct {
	// Enable event history
	EnableHistory bool

	// Maximum history size
	MaxHistorySize int

	// Event TTL for history
	HistoryTTL time.Duration

	// Enable event validation
	EnableValidation bool

	// Default timeout for acknowledgments
	AckTimeout time.Duration

	// Enable event batching
	EnableBatching bool

	// Batch size and interval
	BatchSize     int
	BatchInterval time.Duration
}

EventRouterConfig contains configuration for the event router

type EventThrottler added in v0.6.0

type EventThrottler struct {
	OnThrottled func(event *EventMessage) // Optional handler for throttled events
	// contains filtered or unexported fields
}

EventThrottler throttles events by type

func NewEventThrottler added in v0.6.0

func NewEventThrottler(defaultLimit int, window time.Duration) *EventThrottler

NewEventThrottler creates a new event throttler

func (*EventThrottler) Allow added in v0.6.0

func (t *EventThrottler) Allow(eventType string) bool

Allow checks if an event should be allowed

func (*EventThrottler) SetLimit added in v0.6.0

func (t *EventThrottler) SetLimit(eventType string, limit int)

SetLimit sets a custom limit for an event type

type EventWithAck added in v0.6.0

type EventWithAck struct {
	Event   *EventMessage
	AckChan chan *EventAck
	Timeout time.Duration
}

EventWithAck wraps an event with acknowledgment support

type ExtractSchemaFromTypeOptions added in v0.12.0

type ExtractSchemaFromTypeOptions struct {
	GetTableName      func(t reflect.Type) string
	ToSnakeCasePlural func(s string) string
	ToSingular        func(s string) string

	IncludeOriginalNames bool // Include original Go field names
	IncludeOriginalTypes bool // Include original Go types
	IncludeTagMetadata   bool // Include all struct tags
	IncludeTypeMetadata  bool // Include type hierarchy info

	CustomTagHandlers map[string]func(tag string) any // Handle custom tags
	TagPriority       []string                        // Order of tag precedence

	SkipUnexportedFields *bool                                // Use pointer to distinguish between false and not set
	SkipAnonymousFields  *bool                                // Use pointer to distinguish between false and not set
	CustomFieldFilter    func(field reflect.StructField) bool // Custom field inclusion logic
	FieldNameTransformer func(fieldName string) string        // Custom field name transformation
	PropertyTypeMapper   func(t reflect.Type) PropertyInfo    // Custom type mapping
}

type FiberAdapter

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

func (*FiberAdapter) Init added in v0.1.0

func (a *FiberAdapter) Init()

func (*FiberAdapter) Router

func (a *FiberAdapter) Router() Router[*fiber.App]

func (*FiberAdapter) Serve

func (a *FiberAdapter) Serve(address string) error

func (*FiberAdapter) Shutdown

func (a *FiberAdapter) Shutdown(ctx context.Context) error

func (*FiberAdapter) WrapHandler

func (a *FiberAdapter) WrapHandler(h HandlerFunc) any

func (*FiberAdapter) WrappedRouter

func (a *FiberAdapter) WrappedRouter() *fiber.App

type FiberAdapterConfig added in v0.28.0

type FiberAdapterConfig struct {
	MergeStrategy            RenderMergeStrategy
	ConflictPolicy           *HTTPRouterConflictPolicy
	NamedRoutePolicy         NamedRouteCollisionPolicy
	PathConflictMode         PathConflictMode
	EnforceCatchAllConflicts bool
	EnforceRouteLints        bool
	StrictRoutes             bool
	OrderRoutesBySpecificity bool
}

type FiberErrorHandlerConfig added in v0.26.0

type FiberErrorHandlerConfig struct {
	APIPrefix      string
	FullError      bool
	DelegateNonAPI bool
	ErrorConfig    ErrorHandlerConfig
}

func DefaultFiberErrorHandlerConfig added in v0.26.0

func DefaultFiberErrorHandlerConfig() FiberErrorHandlerConfig

type FiberRouter

type FiberRouter struct {
	BaseRouter
	// contains filtered or unexported fields
}

func (*FiberRouter) Delete

func (r *FiberRouter) Delete(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) Get

func (r *FiberRouter) Get(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) GetPrefix added in v0.0.3

func (r *FiberRouter) GetPrefix() string

func (*FiberRouter) Group

func (r *FiberRouter) Group(prefix string) Router[*fiber.App]

func (*FiberRouter) Handle

func (r *FiberRouter) Handle(method HTTPMethod, pathStr string, handler HandlerFunc, m ...MiddlewareFunc) RouteInfo

func (*FiberRouter) HandleMiss added in v0.56.0

func (r *FiberRouter) HandleMiss(method HTTPMethod, handler HandlerFunc, m ...MiddlewareFunc)

func (*FiberRouter) Head added in v0.1.0

func (r *FiberRouter) Head(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) Mount added in v0.2.0

func (r *FiberRouter) Mount(prefix string) Router[*fiber.App]

TODO: make the same as group but singletong r.routers[prefix] = Group(prefix) return r.routers[prefix]

func (*FiberRouter) Patch

func (r *FiberRouter) Patch(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) Post

func (r *FiberRouter) Post(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) PrintRoutes added in v0.0.2

func (r *FiberRouter) PrintRoutes()

func (*FiberRouter) Put

func (r *FiberRouter) Put(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) Static added in v0.1.0

func (r *FiberRouter) Static(prefix, root string, config ...Static) Router[*fiber.App]

func (*FiberRouter) Use

func (r *FiberRouter) Use(m ...MiddlewareFunc) Router[*fiber.App]

func (*FiberRouter) ValidateRoutes added in v0.47.0

func (r *FiberRouter) ValidateRoutes() []error

func (*FiberRouter) WebSocket added in v0.7.0

func (r *FiberRouter) WebSocket(path string, config WebSocketConfig, handler func(WebSocketContext) error) RouteInfo

func (*FiberRouter) WithGroup added in v0.1.0

func (r *FiberRouter) WithGroup(path string, cb func(r Router[*fiber.App])) Router[*fiber.App]

func (*FiberRouter) WithLogger added in v0.2.1

func (r *FiberRouter) WithLogger(logger Logger) Router[*fiber.App]

type FiberWebSocketFactory added in v0.6.0

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

FiberWebSocketFactory implements WebSocketContextFactory for Fiber

func NewFiberWebSocketFactory added in v0.6.0

func NewFiberWebSocketFactory(logger Logger) *FiberWebSocketFactory

NewFiberWebSocketFactory creates a new Fiber WebSocket factory

func (*FiberWebSocketFactory) AdapterName added in v0.6.0

func (f *FiberWebSocketFactory) AdapterName() string

AdapterName returns the adapter name

func (*FiberWebSocketFactory) CreateWebSocketContext added in v0.6.0

func (f *FiberWebSocketFactory) CreateWebSocketContext(c Context, config WebSocketConfig) (WebSocketContext, error)

CreateWebSocketContext creates a Fiber specific WebSocket context Note: This factory is mainly for testing. In production, use FiberWebSocketHandler

func (*FiberWebSocketFactory) SupportsWebSocket added in v0.6.0

func (f *FiberWebSocketFactory) SupportsWebSocket() bool

SupportsWebSocket returns true as Fiber supports WebSockets

type FileStorage added in v0.6.0

type FileStorage interface {
	Store(ctx context.Context, id string, data []byte, metadata map[string]any) error
	Retrieve(ctx context.Context, id string) ([]byte, map[string]any, error)
	Delete(ctx context.Context, id string) error
	Exists(ctx context.Context, id string) bool
}

FileStorage interface for storing transferred files

type FileTransfer added in v0.6.0

type FileTransfer struct {
	ID          string    `json:"id"`
	Name        string    `json:"name"`
	Size        int64     `json:"size"`
	MimeType    string    `json:"mime_type"`
	Progress    int64     `json:"progress"`
	State       string    `json:"state"` // "pending", "active", "completed", "failed"
	StartTime   time.Time `json:"start_time"`
	EndTime     time.Time `json:"end_time"`
	Error       string    `json:"error,omitempty"`
	Checksum    string    `json:"checksum,omitempty"`
	ChunkSize   int       `json:"chunk_size"`
	TotalChunks int       `json:"total_chunks"`
	// contains filtered or unexported fields
}

FileTransfer represents an active file transfer

type FileTransferManager added in v0.6.0

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

FileTransferManager manages file uploads and downloads

func NewFileTransferManager added in v0.6.0

func NewFileTransferManager(storage FileStorage, maxFileSize int64) *FileTransferManager

NewFileTransferManager creates a new file transfer manager

func (*FileTransferManager) CancelTransfer added in v0.6.0

func (m *FileTransferManager) CancelTransfer(transferID string) error

CancelTransfer cancels an active transfer

func (*FileTransferManager) GetTransfer added in v0.6.0

func (m *FileTransferManager) GetTransfer(transferID string) (*FileTransfer, error)

GetTransfer returns transfer status

func (*FileTransferManager) ReceiveChunk added in v0.6.0

func (m *FileTransferManager) ReceiveChunk(ctx context.Context, transferID string, chunkIndex int, data []byte) error

ReceiveChunk processes an uploaded chunk

func (*FileTransferManager) StartDownload added in v0.6.0

func (m *FileTransferManager) StartDownload(ctx context.Context, client WSClient, fileID string) error

StartDownload initiates a file download

func (*FileTransferManager) StartUpload added in v0.6.0

func (m *FileTransferManager) StartUpload(ctx context.Context, client WSClient, metadata map[string]any) (*FileTransfer, error)

StartUpload initiates a file upload

type FilenameSanitizer added in v0.42.0

type FilenameSanitizer func(string) string

FilenameSanitizer normalizes a filename for download headers.

type GenericEventHandler added in v0.6.0

type GenericEventHandler struct {
	Type      string
	Handler   func(context.Context, WSClient, *EventMessage) error
	Validator func(any) error
}

GenericEventHandler handles events with a generic function

func (*GenericEventHandler) EventType added in v0.6.0

func (h *GenericEventHandler) EventType() string

func (*GenericEventHandler) Handle added in v0.6.0

func (h *GenericEventHandler) Handle(ctx context.Context, client WSClient, event *EventMessage) error

func (*GenericEventHandler) Validate added in v0.6.0

func (h *GenericEventHandler) Validate(data any) error

type HTTPContext added in v0.39.0

type HTTPContext interface {
	Request() *http.Request
	Response() http.ResponseWriter
}

HTTPContext exposes net/http request/response primitives for adapters that support them.

func AsHTTPContext added in v0.39.0

func AsHTTPContext(c Context) (HTTPContext, bool)

AsHTTPContext returns the HTTPContext if the adapter supports it.

type HTTPErrorHandlerConfig added in v0.39.0

type HTTPErrorHandlerConfig struct {
	APIPrefix      string
	FullError      bool
	DelegateNonAPI bool
	ErrorConfig    ErrorHandlerConfig
}

func DefaultHTTPErrorHandlerConfig added in v0.39.0

func DefaultHTTPErrorHandlerConfig() HTTPErrorHandlerConfig

type HTTPMethod

type HTTPMethod string

HTTPMethod represents HTTP request methods

const (
	GET    HTTPMethod = "GET"
	POST   HTTPMethod = "POST"
	PUT    HTTPMethod = "PUT"
	DELETE HTTPMethod = "DELETE"
	PATCH  HTTPMethod = "PATCH"
	HEAD   HTTPMethod = "HEAD"
)

type HTTPRouter

type HTTPRouter struct {
	BaseRouter
	// contains filtered or unexported fields
}

HTTPRouter implements Router for httprouter

func (*HTTPRouter) Delete

func (r *HTTPRouter) Delete(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) Get

func (r *HTTPRouter) Get(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) GetPrefix added in v0.0.3

func (r *HTTPRouter) GetPrefix() string

func (*HTTPRouter) Group

func (r *HTTPRouter) Group(prefix string) Router[*httprouter.Router]

func (*HTTPRouter) Handle

func (r *HTTPRouter) Handle(method HTTPMethod, pathStr string, handler HandlerFunc, m ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) HandleMiss added in v0.56.0

func (r *HTTPRouter) HandleMiss(method HTTPMethod, handler HandlerFunc, m ...MiddlewareFunc)

func (*HTTPRouter) Head added in v0.1.0

func (r *HTTPRouter) Head(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) Mount added in v0.2.0

func (r *HTTPRouter) Mount(prefix string) Router[*httprouter.Router]

func (*HTTPRouter) Patch

func (r *HTTPRouter) Patch(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) Post

func (r *HTTPRouter) Post(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) PrintRoutes added in v0.0.2

func (r *HTTPRouter) PrintRoutes()

func (*HTTPRouter) Put

func (r *HTTPRouter) Put(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) Static added in v0.1.0

func (r *HTTPRouter) Static(prefix, root string, config ...Static) Router[*httprouter.Router]

func (*HTTPRouter) Use

func (*HTTPRouter) ValidateRoutes added in v0.47.0

func (r *HTTPRouter) ValidateRoutes() []error

func (*HTTPRouter) WebSocket added in v0.7.0

func (r *HTTPRouter) WebSocket(path string, config WebSocketConfig, handler func(WebSocketContext) error) RouteInfo

func (*HTTPRouter) WithGroup added in v0.1.0

func (r *HTTPRouter) WithGroup(path string, cb func(r Router[*httprouter.Router])) Router[*httprouter.Router]

func (*HTTPRouter) WithLogger added in v0.2.1

func (r *HTTPRouter) WithLogger(logger Logger) Router[*httprouter.Router]

type HTTPRouterConflictPolicy added in v0.41.0

type HTTPRouterConflictPolicy int

HTTPRouterConflictPolicy controls how route conflicts are handled. Note: HTTPRouterConflictLogAndContinue behaves like log-and-skip for httprouter because the underlying router does not allow conflicting routes.

const (
	HTTPRouterConflictPanic HTTPRouterConflictPolicy = iota
	HTTPRouterConflictLogAndSkip
	HTTPRouterConflictLogAndContinue
)

func (HTTPRouterConflictPolicy) String added in v0.41.0

func (p HTTPRouterConflictPolicy) String() string

type HTTPRouterWebSocketFactory added in v0.6.0

type HTTPRouterWebSocketFactory struct{}

HTTPRouterWebSocketFactory implements WebSocketContextFactory for HTTPRouter

func NewHTTPRouterWebSocketFactory added in v0.6.0

func NewHTTPRouterWebSocketFactory(_ Views) *HTTPRouterWebSocketFactory

NewHTTPRouterWebSocketFactory creates a new HTTPRouter WebSocket factory

func (*HTTPRouterWebSocketFactory) AdapterName added in v0.6.0

func (f *HTTPRouterWebSocketFactory) AdapterName() string

AdapterName returns the adapter name

func (*HTTPRouterWebSocketFactory) CreateWebSocketContext added in v0.6.0

func (f *HTTPRouterWebSocketFactory) CreateWebSocketContext(c Context, config WebSocketConfig) (WebSocketContext, error)

CreateWebSocketContext creates an HTTPRouter-specific WebSocket context

func (*HTTPRouterWebSocketFactory) SupportsWebSocket added in v0.6.0

func (f *HTTPRouterWebSocketFactory) SupportsWebSocket() bool

SupportsWebSocket returns true as HTTPRouter supports WebSockets

type HTTPServer

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

func (*HTTPServer) Init added in v0.1.0

func (a *HTTPServer) Init()

func (*HTTPServer) Router

func (a *HTTPServer) Router() Router[*httprouter.Router]

func (*HTTPServer) Serve

func (a *HTTPServer) Serve(address string) error

func (*HTTPServer) Shutdown

func (a *HTTPServer) Shutdown(ctx context.Context) error

func (*HTTPServer) WrapHandler

func (a *HTTPServer) WrapHandler(h HandlerFunc) any

func (*HTTPServer) WrappedRouter

func (a *HTTPServer) WrappedRouter() *httprouter.Router

type HandlerFunc

type HandlerFunc func(Context) error

func HandlerFromHTTP added in v0.39.0

func HandlerFromHTTP(h http.Handler) HandlerFunc

HandlerFromHTTP adapts a net/http handler to a go-router HandlerFunc. Works with any Context that also implements HTTPContext.

func SSEClientCORSMiddleware added in v0.54.0

func SSEClientCORSMiddleware() HandlerFunc

SSEClientCORSMiddleware handles OPTIONS requests for embedded SSE client assets.

func SSEClientHandler added in v0.54.0

func SSEClientHandler(minified bool) HandlerFunc

SSEClientHandler serves the browser-targeted SSE client bundle. When minified is true it serves the minified IIFE build, otherwise it serves the development IIFE build with sourcemap references.

func SSEClientInfoHandler added in v0.54.0

func SSEClientInfoHandler() HandlerFunc

SSEClientInfoHandler serves embedded SSE client metadata as JSON.

func SSEClientModuleHandler added in v0.54.0

func SSEClientModuleHandler() HandlerFunc

SSEClientModuleHandler serves the ESM build for module-aware applications.

func SSEClientSourceMapHandler added in v0.54.0

func SSEClientSourceMapHandler() HandlerFunc

SSEClientSourceMapHandler serves the source map for the non-minified IIFE build.

func SSEClientTypesHandler added in v0.54.0

func SSEClientTypesHandler() HandlerFunc

SSEClientTypesHandler serves TypeScript declarations for the embedded client.

func WSClientHandler added in v0.8.0

func WSClientHandler() HandlerFunc

WSClientHandler serves the regular (non-minified) WebSocket client

func WSClientMinHandler added in v0.8.0

func WSClientMinHandler() HandlerFunc

WSClientMinHandler serves the minified WebSocket client

func WSClientTypesHandler added in v0.8.0

func WSClientTypesHandler() HandlerFunc

WSClientTypesHandler serves TypeScript definitions

func WSExamplesHandler added in v0.8.0

func WSExamplesHandler() HandlerFunc

WSExamplesHandler serves usage examples

func WSTestHandler added in v0.8.0

func WSTestHandler() HandlerFunc

WSTestHandler serves the interactive test page

func WebSocketClientCORSMiddleware added in v0.8.0

func WebSocketClientCORSMiddleware() HandlerFunc

Options middleware for CORS preflight requests

func WebSocketClientHandler added in v0.8.0

func WebSocketClientHandler(minified bool) HandlerFunc

WebSocketClientHandler serves the main WebSocket client library @param minified bool - serve minified version if true

func WebSocketClientInfoHandler added in v0.8.0

func WebSocketClientInfoHandler() HandlerFunc

WebSocketClientInfoHandler serves client information as JSON

func WebSocketClientTypesHandler added in v0.8.0

func WebSocketClientTypesHandler() HandlerFunc

WebSocketClientTypesHandler serves TypeScript definitions

func WebSocketExamplesHandler added in v0.8.0

func WebSocketExamplesHandler() HandlerFunc

WebSocketExamplesHandler serves usage examples

func WebSocketTestHandler added in v0.8.0

func WebSocketTestHandler() HandlerFunc

WebSocketTestHandler serves the interactive test page

func WebsocketClientMinMapHandler added in v0.8.0

func WebsocketClientMinMapHandler() HandlerFunc

WebSocketExamplesHandler serves usage examples

func WrapHandler added in v0.0.2

func WrapHandler(handler func(Context) error) HandlerFunc

WrapHandler function to wrap handlers that return error

func (HandlerFunc) AsMiddlware added in v0.0.2

func (h HandlerFunc) AsMiddlware() MiddlewareFunc

type HeartbeatManager added in v0.6.0

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

HeartbeatManager manages client heartbeats

func NewHeartbeatManager added in v0.6.0

func NewHeartbeatManager(interval, timeout time.Duration, onTimeout func(string)) *HeartbeatManager

NewHeartbeatManager creates a new heartbeat manager

func (*HeartbeatManager) HandlePong added in v0.6.0

func (h *HeartbeatManager) HandlePong(clientID string)

HandlePong handles a pong message from a client

func (*HeartbeatManager) StartHeartbeat added in v0.6.0

func (h *HeartbeatManager) StartHeartbeat(client WSClient)

StartHeartbeat starts heartbeat monitoring for a client

func (*HeartbeatManager) StopHeartbeat added in v0.6.0

func (h *HeartbeatManager) StopHeartbeat(clientID string)

StopHeartbeat stops heartbeat monitoring for a client

type JSONHandler added in v0.6.0

type JSONHandler func(ctx context.Context, data json.RawMessage) error

JSONHandler handles JSON messages with context and error support

type JSONMessage added in v0.6.0

type JSONMessage struct {
	Type      string          `json:"type"`
	ID        string          `json:"id,omitempty"`
	Timestamp time.Time       `json:"timestamp"`
	Data      json.RawMessage `json:"data"`
}

JSONMessage represents a standard JSON message structure

type JSONMessageHandler added in v0.6.0

type JSONMessageHandler func(ctx WebSocketContext, msg *JSONMessage) error

JSONMessageHandler handles JSON messages

type JSONMessageRouter added in v0.6.0

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

JSONMessageRouter routes JSON messages based on type

func NewJSONMessageRouter added in v0.6.0

func NewJSONMessageRouter(maxSize int64) *JSONMessageRouter

NewJSONMessageRouter creates a new JSON message router

func (*JSONMessageRouter) Register added in v0.6.0

func (r *JSONMessageRouter) Register(msgType string, handler JSONMessageHandler)

Register registers a handler for a message type

func (*JSONMessageRouter) Route added in v0.6.0

Route routes a message to the appropriate handler

type Logger added in v0.0.2

type Logger interface {
	Debug(format string, args ...any)
	Info(format string, args ...any)
	Warn(format string, args ...any)
	Error(format string, args ...any)
}

type MemoryFileStorage added in v0.6.0

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

MemoryFileStorage stores files in memory

func NewMemoryFileStorage added in v0.6.0

func NewMemoryFileStorage() *MemoryFileStorage

NewMemoryFileStorage creates a new memory file storage

func (*MemoryFileStorage) Delete added in v0.6.0

func (s *MemoryFileStorage) Delete(ctx context.Context, id string) error

Delete deletes a file from memory

func (*MemoryFileStorage) Exists added in v0.6.0

func (s *MemoryFileStorage) Exists(ctx context.Context, id string) bool

Exists checks if a file exists

func (*MemoryFileStorage) Retrieve added in v0.6.0

func (s *MemoryFileStorage) Retrieve(ctx context.Context, id string) ([]byte, map[string]any, error)

Retrieve retrieves a file from memory

func (*MemoryFileStorage) Store added in v0.6.0

func (s *MemoryFileStorage) Store(ctx context.Context, id string, data []byte, metadata map[string]any) error

Store stores a file in memory

type MessageHandler added in v0.6.0

type MessageHandler func(ctx context.Context, data []byte) error

MessageHandler handles raw messages with context and error support

type MessageQueue added in v0.6.0

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

MessageQueue stores messages for offline clients

func NewMessageQueue added in v0.6.0

func NewMessageQueue(maxSize int, ttl time.Duration) *MessageQueue

NewMessageQueue creates a new message queue

func (*MessageQueue) Add added in v0.6.0

func (q *MessageQueue) Add(msg *QueuedMessage) error

Add adds a message to the queue

func (*MessageQueue) Flush added in v0.6.0

func (q *MessageQueue) Flush() []*QueuedMessage

Flush returns all messages and clears the queue

func (*MessageQueue) Size added in v0.6.0

func (q *MessageQueue) Size() int

Size returns the number of messages in the queue

type MessageQueueConfig added in v0.6.0

type MessageQueueConfig struct {
	MaxQueueSize        int
	MessageTTL          time.Duration
	MaxDeliveryAttempts int
	PersistQueues       bool
}

MessageQueueConfig contains message queue configuration

type MessageQueueManager added in v0.6.0

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

MessageQueueManager manages message queues for all clients

func NewMessageQueueManager added in v0.6.0

func NewMessageQueueManager(config MessageQueueConfig) *MessageQueueManager

NewMessageQueueManager creates a new message queue manager

func (*MessageQueueManager) GetQueue added in v0.6.0

func (m *MessageQueueManager) GetQueue(clientID string) *MessageQueue

GetQueue returns or creates a queue for a client

func (*MessageQueueManager) RemoveQueue added in v0.6.0

func (m *MessageQueueManager) RemoveQueue(clientID string)

RemoveQueue removes a client's queue

type MessageQueueStorage added in v0.6.0

type MessageQueueStorage interface {
	Store(ctx context.Context, clientID string, messages []*QueuedMessage) error
	Retrieve(ctx context.Context, clientID string) ([]*QueuedMessage, error)
	Delete(ctx context.Context, clientID string) error
}

MessageQueueStorage interface for persistent queue storage

type MetadataAggregator added in v0.0.3

type MetadataAggregator struct {
	Paths      map[string]any
	Schemas    map[string]any
	Tags       []any
	Components map[string]any

	RelationDescriptors map[string]*RelationDescriptor
	// contains filtered or unexported fields
}

MetadataAggregator collects and merges metadata from multiple providers

func NewMetadataAggregator added in v0.0.3

func NewMetadataAggregator() *MetadataAggregator

NewMetadataAggregator creates a new aggregator

func (*MetadataAggregator) AddProvider added in v0.0.3

func (ma *MetadataAggregator) AddProvider(provider MetadataProvider)

AddProvider adds a metadata provider to the aggregator

func (*MetadataAggregator) AddProviders added in v0.0.3

func (ma *MetadataAggregator) AddProviders(providers ...MetadataProvider)

AddProviders adds multiple metadata providers to the aggregator

func (*MetadataAggregator) Clone added in v0.18.0

Clone creates a shallow copy of the aggregator with shared providers.

func (*MetadataAggregator) Compile added in v0.0.3

func (ma *MetadataAggregator) Compile()

GenerateOpenAPI generates a complete OpenAPI specification from all providers

func (*MetadataAggregator) GenerateOpenAPI added in v0.0.3

func (ma *MetadataAggregator) GenerateOpenAPI() map[string]any

func (*MetadataAggregator) SetInfo added in v0.21.0

func (ma *MetadataAggregator) SetInfo(info OpenAPIInfo)

SetInfo configures the top-level OpenAPI info object.

func (*MetadataAggregator) SetTags added in v0.0.3

func (ma *MetadataAggregator) SetTags(tags []string)

SetTags sets global tags that will be added to all operations

func (*MetadataAggregator) WithRelationProvider added in v0.22.0

func (ma *MetadataAggregator) WithRelationProvider(provider RelationMetadataProvider) *MetadataAggregator

WithRelationProvider sets the default relation metadata provider.

func (*MetadataAggregator) WithRelationProviders added in v0.22.0

func (ma *MetadataAggregator) WithRelationProviders(overrides map[reflect.Type]RelationMetadataProvider) *MetadataAggregator

WithRelationProviders registers per-resource relation metadata providers.

func (*MetadataAggregator) WithUISchemaOptions added in v0.23.0

func (ma *MetadataAggregator) WithUISchemaOptions(opts UISchemaOptions) *MetadataAggregator

WithUISchemaOptions registers UI schema enrichment configuration.

type MetadataProvider added in v0.0.3

type MetadataProvider interface {
	GetMetadata() ResourceMetadata
}

MetadataProvider interface for components that can provide API metadata

type MiddlewareFunc added in v0.0.2

type MiddlewareFunc func(HandlerFunc) HandlerFunc

func AdvancedWebSocketMiddleware added in v0.6.0

func AdvancedWebSocketMiddleware(config WebSocketConfig) MiddlewareFunc

AdvancedWebSocketMiddleware creates middleware with all advanced features

func DefaultWebSocketMiddleware added in v0.6.0

func DefaultWebSocketMiddleware() MiddlewareFunc

DefaultWebSocketMiddleware creates WebSocket middleware with default configuration

func MiddlewareFromFiber added in v0.0.3

func MiddlewareFromFiber(userFiberMw func(*fiber.Ctx) error) MiddlewareFunc

MiddlewareFromFiber adapts a user-provided Fiber middleware to your router's chain, preserving c.Next() semantics by spinning up a sub-Fiber app for each request.

func MiddlewareFromHTTP added in v0.0.2

func MiddlewareFromHTTP(mw func(next http.Handler) http.Handler) MiddlewareFunc

MiddlewareFromHTTP that transforms a standard Go HTTP middleware which takes and returns http.Handler, into a MiddlewareFunc suitable for use with our router. This function essentially adapts the http.Handler pattern to the HandlerFunc (Context) error interface

func OriginProtection added in v0.55.0

func OriginProtection(config ...OriginProtectionConfig) MiddlewareFunc

func SecurityMiddleware added in v0.6.0

func SecurityMiddleware(policy WebSocketSecurityPolicy) MiddlewareFunc

SecurityMiddleware creates middleware that enforces WebSocket security policies

func ToMiddleware added in v0.0.2

func ToMiddleware(h HandlerFunc) MiddlewareFunc

ToMiddleware function to wrap handlers and run them as a middleware

func WebSocketMiddlewareWithOrigins added in v0.6.0

func WebSocketMiddlewareWithOrigins(origins ...string) MiddlewareFunc

WebSocketMiddlewareWithOrigins creates WebSocket middleware that only allows specific origins

func WebSocketMiddlewareWithSubprotocols added in v0.6.0

func WebSocketMiddlewareWithSubprotocols(protocols ...string) MiddlewareFunc

WebSocketMiddlewareWithSubprotocols creates WebSocket middleware that supports specific subprotocols

func WebSocketUpgrade added in v0.6.0

func WebSocketUpgrade(config WebSocketConfig) MiddlewareFunc

WebSocketUpgrade creates middleware that handles WebSocket upgrade requests

func WithErrorHandlerMiddleware added in v0.0.2

func WithErrorHandlerMiddleware(opts ...ErrorHandlerOption) MiddlewareFunc

WithErrorHandlerMiddleware creates a middleware that handles errors for all routes in a group

type MissHandlerRegistrar added in v0.56.0

type MissHandlerRegistrar interface {
	HandleMiss(method HTTPMethod, handler HandlerFunc, middlewares ...MiddlewareFunc)
}

MissHandlerRegistrar allows adapters to handle unmatched requests without claiming a concrete route path. This is useful for guarded fallback flows that must coexist with explicit static routes.

type MockContext added in v0.2.4

type MockContext struct {
	mock.Mock
	NextCalled    bool
	HeadersM      map[string]string
	CookiesM      map[string]string
	ParamsM       map[string]string
	QueriesM      map[string]string
	LocalsMock    map[any]any
	StatusCodeM   int
	ResponseBodyM string
}

MockContext for testing providing testify mock for all methods, and direct field access for commonly used methods like Header, Param, Query, etc to make testing easier

func NewMockContext added in v0.2.4

func NewMockContext() *MockContext

func (*MockContext) Bind added in v0.2.4

func (m *MockContext) Bind(i any) error

func (*MockContext) BindJSON added in v0.2.4

func (m *MockContext) BindJSON(i any) error

func (*MockContext) BindQuery added in v0.2.4

func (m *MockContext) BindQuery(i any) error

func (*MockContext) BindXML added in v0.2.4

func (m *MockContext) BindXML(i any) error

func (*MockContext) Body added in v0.2.4

func (m *MockContext) Body() []byte

func (*MockContext) Context added in v0.2.4

func (m *MockContext) Context() context.Context

func (*MockContext) Cookie added in v0.2.4

func (m *MockContext) Cookie(cookie *Cookie)

func (*MockContext) CookieParser added in v0.2.4

func (m *MockContext) CookieParser(i any) error

func (*MockContext) Cookies added in v0.2.4

func (m *MockContext) Cookies(key string, defaultValue ...string) string

func (*MockContext) FormFile added in v0.2.4

func (m *MockContext) FormFile(key string) (*multipart.FileHeader, error)

func (*MockContext) FormValue added in v0.2.4

func (m *MockContext) FormValue(key string, defaultValue ...string) string

func (*MockContext) Get added in v0.2.4

func (m *MockContext) Get(key string, defaultValue any) any

func (*MockContext) GetBool added in v0.2.4

func (m *MockContext) GetBool(key string, defaultValue bool) bool

func (*MockContext) GetInt added in v0.2.4

func (m *MockContext) GetInt(key string, def int) int

func (*MockContext) GetString added in v0.2.4

func (m *MockContext) GetString(key string, defaultValue string) string

func (*MockContext) Header added in v0.2.4

func (m *MockContext) Header(key string) string

func (*MockContext) IP added in v0.14.0

func (m *MockContext) IP() string

func (*MockContext) JSON added in v0.2.4

func (m *MockContext) JSON(code int, val any) error

func (*MockContext) Locals added in v0.2.4

func (m *MockContext) Locals(key any, value ...any) any

func (*MockContext) LocalsMerge added in v0.11.0

func (m *MockContext) LocalsMerge(key any, value map[string]any) map[string]any

func (*MockContext) Method added in v0.2.4

func (m *MockContext) Method() string

func (*MockContext) Next added in v0.2.4

func (m *MockContext) Next() error

func (*MockContext) NoContent added in v0.2.4

func (m *MockContext) NoContent(code int) error

func (*MockContext) OnNext added in v0.2.4

func (m *MockContext) OnNext(callback func() error)

func (*MockContext) OriginalURL added in v0.2.4

func (m *MockContext) OriginalURL() string

func (*MockContext) Param added in v0.2.4

func (m *MockContext) Param(key string, defaultValue ...string) string

func (*MockContext) ParamsInt added in v0.2.4

func (m *MockContext) ParamsInt(key string, defaultValue int) int

func (*MockContext) Path added in v0.2.4

func (m *MockContext) Path() string

func (*MockContext) Queries added in v0.2.4

func (m *MockContext) Queries() map[string]string

func (*MockContext) Query added in v0.2.4

func (m *MockContext) Query(key string, defaultValue ...string) string

func (*MockContext) QueryInt added in v0.2.4

func (m *MockContext) QueryInt(key string, defaultValue int) int

func (*MockContext) QueryValues added in v0.39.0

func (m *MockContext) QueryValues(key string) []string

func (*MockContext) Redirect added in v0.2.4

func (m *MockContext) Redirect(path string, status ...int) error

func (*MockContext) RedirectBack added in v0.2.4

func (m *MockContext) RedirectBack(fallback string, status ...int) error

func (*MockContext) RedirectToRoute added in v0.2.4

func (m *MockContext) RedirectToRoute(name string, data ViewContext, status ...int) error

func (*MockContext) Referer added in v0.2.4

func (m *MockContext) Referer() string

func (*MockContext) Render added in v0.2.4

func (m *MockContext) Render(name string, bind any, layout ...string) error

func (*MockContext) RouteName added in v0.9.0

func (m *MockContext) RouteName() string

func (*MockContext) RouteParams added in v0.9.0

func (m *MockContext) RouteParams() map[string]string

func (*MockContext) Send added in v0.2.4

func (m *MockContext) Send(b []byte) error

func (*MockContext) SendStatus added in v0.2.4

func (m *MockContext) SendStatus(code int) error

func (*MockContext) SendStream added in v0.39.0

func (m *MockContext) SendStream(r io.Reader) error

func (*MockContext) SendString added in v0.2.4

func (m *MockContext) SendString(s string) error

func (*MockContext) Set added in v0.2.4

func (m *MockContext) Set(key string, val any)

func (*MockContext) SetContext added in v0.2.4

func (m *MockContext) SetContext(ctx context.Context)

func (*MockContext) SetHeader added in v0.2.4

func (m *MockContext) SetHeader(key, val string) Context

func (*MockContext) Status added in v0.2.4

func (m *MockContext) Status(code int) Context

type NamedHandler added in v0.0.2

type NamedHandler struct {
	Name    string
	Handler HandlerFunc
}

NamedHandler is a handler with a name for debugging/printing

type NamedRouteCollisionPolicy added in v0.53.0

type NamedRouteCollisionPolicy string
const (
	NamedRouteCollisionPolicyReplace NamedRouteCollisionPolicy = "replace"
	NamedRouteCollisionPolicyError   NamedRouteCollisionPolicy = "error"
	NamedRouteCollisionPolicySkip    NamedRouteCollisionPolicy = "skip"
)

func (NamedRouteCollisionPolicy) String added in v0.53.0

func (p NamedRouteCollisionPolicy) String() string

type NamespaceAuthFunc added in v0.6.0

type NamespaceAuthFunc func(ctx context.Context, client WSClient) error

NamespaceAuthFunc authorizes access to a namespace

type NamespaceResolver added in v0.51.0

type NamespaceResolver[NS ~string] struct {
	// contains filtered or unexported fields
}

NamespaceResolver resolves namespace + route-key mappings into canonical paths.

func NewNamespaceResolver added in v0.51.0

func NewNamespaceResolver[NS ~string](namespaces map[NS]string, routes map[NS]map[string]string) NamespaceResolver[NS]

NewNamespaceResolver creates a namespace + route-key resolver. Input maps are copied so caller mutations do not affect resolver behavior.

func (NamespaceResolver[NS]) MustNamespace added in v0.51.0

func (r NamespaceResolver[NS]) MustNamespace(ns NS) string

MustNamespace returns Namespace(ns) and panics on error.

func (NamespaceResolver[NS]) MustRelative added in v0.51.0

func (r NamespaceResolver[NS]) MustRelative(ns NS, routeKey string) string

MustRelative returns Relative(ns, routeKey) and panics on error.

func (NamespaceResolver[NS]) MustResolve added in v0.51.0

func (r NamespaceResolver[NS]) MustResolve(ns NS, routeKey string) string

MustResolve returns Resolve(ns, routeKey) and panics on error.

func (NamespaceResolver[NS]) Namespace added in v0.51.0

func (r NamespaceResolver[NS]) Namespace(ns NS) (string, error)

Namespace returns the canonical namespace base path.

func (NamespaceResolver[NS]) Relative added in v0.51.0

func (r NamespaceResolver[NS]) Relative(ns NS, routeKey string) (string, error)

Relative returns a canonical path relative to the namespace base.

func (NamespaceResolver[NS]) Resolve added in v0.51.0

func (r NamespaceResolver[NS]) Resolve(ns NS, routeKey string) (string, error)

Resolve returns the full canonical path for namespace + route key.

type OpenAPIFieldContact added in v0.0.2

type OpenAPIFieldContact struct {
	Email string
	Name  string
	URL   string
}

type OpenAPIInfo added in v0.1.0

type OpenAPIInfo struct {
	Title          string
	Version        string
	Description    string
	TermsOfService string
	Contact        OpenAPIFieldContact
	License        OpenAPIInfoLicense
}

type OpenAPIInfoLicense added in v0.1.0

type OpenAPIInfoLicense struct {
	Name string
	Url  string
}

type OpenAPIOption added in v0.0.2

type OpenAPIOption func(*openAPIConfig)

func WithDocsPath added in v0.0.2

func WithDocsPath(path string) OpenAPIOption

func WithOpenAPIEndpointsInSpec added in v0.18.0

func WithOpenAPIEndpointsInSpec(include bool) OpenAPIOption

func WithOpenAPIPath added in v0.0.2

func WithOpenAPIPath(path string) OpenAPIOption

func WithTitle added in v0.0.2

func WithTitle(title string) OpenAPIOption

type OpenAPIRenderer added in v0.0.2

type OpenAPIRenderer struct {
	Info *OpenAPIInfo

	Servers  []OpenAPIServer
	Security []OpenAPISecuritySchemas
	// TODO: Remove
	Title          string
	Version        string
	Description    string
	TermsOfService string
	Contact        *OpenAPIFieldContact
	License        *OpenAPIInfoLicense

	Routes     []RouteDefinition
	Paths      map[string]any
	Tags       []any
	Components map[string]any
	// contains filtered or unexported fields
}

func NewOpenAPIRenderer added in v0.1.0

func NewOpenAPIRenderer(overrides ...OpenAPIRenderer) *OpenAPIRenderer

func (*OpenAPIRenderer) AppenRouteInfo added in v0.0.3

func (o *OpenAPIRenderer) AppenRouteInfo(routes []RouteDefinition) *OpenAPIRenderer

AppenRouteInfo updates the renderer with route information

func (*OpenAPIRenderer) AppendServer added in v0.1.0

func (o *OpenAPIRenderer) AppendServer(url, description string) *OpenAPIRenderer

func (*OpenAPIRenderer) GenerateOpenAPI added in v0.0.2

func (o *OpenAPIRenderer) GenerateOpenAPI() map[string]any

func (*OpenAPIRenderer) WithMetadataProviders added in v0.0.3

func (o *OpenAPIRenderer) WithMetadataProviders(providers ...OpenApiMetaGenerator) *OpenAPIRenderer

type OpenAPISecurity added in v0.1.0

type OpenAPISecurity struct {
	Name         string
	Requirements []SecurityRequirement
}

type OpenAPISecuritySchema added in v0.1.0

type OpenAPISecuritySchema struct {
	Name        string
	Type        string
	In          string
	Description string
}

type OpenAPISecuritySchemas added in v0.1.0

type OpenAPISecuritySchemas struct {
	Name    string
	Schemas []OpenAPISecuritySchema
}

type OpenAPIServer added in v0.1.0

type OpenAPIServer struct {
	Url         string
	Description string
}

type OpenApiMetaGenerator added in v0.0.3

type OpenApiMetaGenerator interface {
	GenerateOpenAPI() map[string]any
}

type OriginProtectionConfig added in v0.55.0

type OriginProtectionConfig struct {
	Skip                  func(Context) bool
	AllowedOrigins        []string
	AllowSameOrigin       bool
	UnsafeMethods         []string
	TrustForwardedHeaders bool
	ErrorHandler          ErrorHandler
}

type OwnedRouteSet added in v0.53.0

type OwnedRouteSet struct {
	Owner  string
	Routes []RouteDefinition
}

type OwnerRoutePolicy added in v0.53.0

type OwnerRoutePolicy struct {
	Owner             string
	AllowedPrefixes   []string
	RouteNamePrefixes []string
}

type Parameter added in v0.0.2

type Parameter struct {
	Ref         string         `json:"-"`
	Name        string         `json:"name"`
	In          string         `json:"in"` // query, path, header, cookie
	Required    bool           `json:"required"`
	Description string         `json:"description,omitempty"`
	Schema      map[string]any `json:"schema,omitempty"`
	Example     any            `json:"example,omitempty"`
}

Parameter unifies the parameter definitions

type PathConflictMode added in v0.47.0

type PathConflictMode string

PathConflictMode controls how static and wildcard path segments are treated.

const (
	// PathConflictModeStrict preserves current behavior and treats static/param siblings as conflicts.
	PathConflictModeStrict PathConflictMode = "strict"
	// PathConflictModePreferStatic allows static/param siblings and relies on specificity ordering.
	PathConflictModePreferStatic PathConflictMode = "prefer_static"
)

func (PathConflictMode) String added in v0.47.0

func (m PathConflictMode) String() string

type PingPongManager added in v0.6.0

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

PingPongManager manages ping/pong for HTTPRouter WebSocket connections

func NewPingPongManager added in v0.6.0

func NewPingPongManager(conn *websocket.Conn, pingPeriod, pongWait time.Duration) *PingPongManager

NewPingPongManager creates a new ping/pong manager

func (*PingPongManager) Start added in v0.6.0

func (m *PingPongManager) Start()

Start starts the ping/pong loop

func (*PingPongManager) Stop added in v0.6.0

func (m *PingPongManager) Stop()

Stop stops the ping/pong loop

type PrefixedRouter added in v0.0.3

type PrefixedRouter interface {
	GetPrefix() string
}

TODO: Maybe incorporate into Router[T]

type PropertyInfo added in v0.0.3

type PropertyInfo struct {
	Type          string                  `json:"type"`
	Format        string                  `json:"format,omitempty"`
	Description   string                  `json:"description,omitempty"`
	Required      bool                    `json:"required"`
	Nullable      bool                    `json:"nullable"`
	ReadOnly      bool                    `json:"read_only"`
	WriteOnly     bool                    `json:"write_only"`
	OriginalName  string                  `json:"original_name"`
	Example       any                     `json:"example,omitempty"`
	Properties    map[string]PropertyInfo `json:"properties,omitempty"`    // For nested objects
	Items         *PropertyInfo           `json:"items,omitempty"`         // For arrays
	OriginalType  string                  `json:"originalType,omitempty"`  // Go type string
	OriginalKind  reflect.Kind            `json:"originalKind,omitempty"`  // Go kind
	AllTags       map[string]string       `json:"allTags,omitempty"`       // All struct tags
	TransformPath []string                `json:"transformPath,omitempty"` // Transformation steps
	GoPackage     string                  `json:"goPackage,omitempty"`     // Package path
	CustomTagData map[string]any          `json:"customTagData,omitempty"` // Custom tag handler results
	RelationName  string                  `json:"-"`                       // Populated for relation-backed fields
	RelatedSchema string                  `json:"-"`                       // Target schema/component name
}

type QueuedMessage added in v0.6.0

type QueuedMessage struct {
	ID        string         `json:"id"`
	Type      string         `json:"type"`
	Data      any            `json:"data"`
	Metadata  map[string]any `json:"metadata"`
	Timestamp time.Time      `json:"timestamp"`
	Attempts  int            `json:"attempts"`
}

QueuedMessage represents a queued message

type ReconnectConfig added in v0.6.0

type ReconnectConfig struct {
	// Enable reconnection support
	Enabled bool

	// Session timeout (how long to keep session after disconnect)
	SessionTimeout time.Duration

	// Maximum reconnection attempts
	MaxReconnectAttempts int

	// Reconnection backoff settings
	InitialBackoff time.Duration
	MaxBackoff     time.Duration
	BackoffFactor  float64

	// Message queue settings
	EnableMessageQueue bool
	MaxQueueSize       int
	QueueTTL           time.Duration

	// Heartbeat settings
	HeartbeatInterval time.Duration
	HeartbeatTimeout  time.Duration
}

ReconnectConfig contains reconnection configuration

func DefaultReconnectConfig added in v0.6.0

func DefaultReconnectConfig() ReconnectConfig

DefaultReconnectConfig returns default reconnection configuration

type ReconnectManager added in v0.6.0

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

ReconnectManager manages WebSocket reconnection logic

func NewReconnectManager added in v0.6.0

func NewReconnectManager(config ReconnectConfig) *ReconnectManager

NewReconnectManager creates a new reconnection manager

func (*ReconnectManager) CreateSession added in v0.6.0

func (m *ReconnectManager) CreateSession(client WSClient) (*ClientSession, error)

CreateSession creates a new session for a client

func (*ReconnectManager) HandleDisconnect added in v0.6.0

func (m *ReconnectManager) HandleDisconnect(sessionID string)

HandleDisconnect handles client disconnection

func (*ReconnectManager) HandleReconnect added in v0.6.0

func (m *ReconnectManager) HandleReconnect(ctx context.Context, client WSClient, sessionID, token string) (*ClientSession, error)

HandleReconnect handles client reconnection

func (*ReconnectManager) QueueMessage added in v0.6.0

func (m *ReconnectManager) QueueMessage(sessionID string, message *QueuedMessage) error

QueueMessage queues a message for a disconnected client

func (*ReconnectManager) RemoveSession added in v0.6.0

func (m *ReconnectManager) RemoveSession(sessionID string)

RemoveSession removes a session

type RelationDescriptor added in v0.22.0

type RelationDescriptor struct {
	Tree      *RelationNode  `json:"tree,omitempty"`
	Includes  []string       `json:"includes,omitempty"`
	Relations []RelationInfo `json:"relations,omitempty"`
}

RelationDescriptor bundles relation tree data with flattened include metadata.

func ApplyRelationFilters added in v0.22.0

func ApplyRelationFilters(resourceType reflect.Type, descriptor *RelationDescriptor) *RelationDescriptor

ApplyRelationFilters runs all registered filters against the descriptor.

type RelationFilter added in v0.22.0

type RelationFilter struct {
	Field    string `json:"field"`
	Operator string `json:"operator"`
	Value    string `json:"value"`
}

RelationFilter represents an allowed filter on a relation path.

type RelationFilterFunc added in v0.22.0

type RelationFilterFunc func(resourceType reflect.Type, descriptor *RelationDescriptor) *RelationDescriptor

RelationFilterFunc allows frameworks to mutate relation metadata prior to publication.

type RelationInfo added in v0.22.0

type RelationInfo struct {
	Name    string           `json:"name"`
	Filters []RelationFilter `json:"filters,omitempty"`
}

RelationInfo captures relation-level filter metadata for a given include path.

type RelationMetadataProvider added in v0.22.0

type RelationMetadataProvider interface {
	BuildRelationDescriptor(resourceType reflect.Type) (*RelationDescriptor, error)
}

RelationMetadataProvider generates relation metadata for the supplied resource type.

type RelationNode added in v0.22.0

type RelationNode struct {
	Name      string                   `json:"name"`
	Display   string                   `json:"display,omitempty"`
	TypeName  string                   `json:"typeName,omitempty"`
	Fields    []string                 `json:"fields,omitempty"`
	Aliases   []string                 `json:"aliases,omitempty"`
	Operators []string                 `json:"operators,omitempty"`
	Children  map[string]*RelationNode `json:"children,omitempty"`
}

RelationNode describes an entity and its nested relations for metadata purposes.

type RelationshipInfo added in v0.2.0

type RelationshipInfo struct {
	RelationType      string           `json:"relation_type"` // e.g. has-one, has-many, belongs-to, many-to-many
	Cardinality       string           `json:"cardinality,omitempty"`
	RelatedTypeName   string           `json:"related_type_name"`
	RelatedSchema     string           `json:"related_schema,omitempty"`
	RelatedType       reflect.Type     `json:"-"`
	IsSlice           bool             `json:"is_slice"`
	JoinClause        string           `json:"join_clause,omitempty"`
	JoinKey           string           `json:"join_key,omitempty"`
	PrimaryKey        string           `json:"primary_key,omitempty"`
	ForeignKey        string           `json:"foreign_key,omitempty"`
	PivotTable        string           `json:"pivot_table,omitempty"`         // e.g. "order_to_items"
	PivotJoin         string           `json:"pivot_join,omitempty"`          // e.g. "Order=Item"
	SourceTable       string           `json:"source_table,omitempty"`        // entity owning the relationship field
	SourceColumn      string           `json:"source_column,omitempty"`       // FK column on the source table
	TargetTable       string           `json:"target_table,omitempty"`        // referenced entity/table
	TargetColumn      string           `json:"target_column,omitempty"`       // PK column on the target table
	SourcePivotColumn string           `json:"source_pivot_column,omitempty"` // for M2M: column linking to source table
	TargetPivotColumn string           `json:"target_pivot_column,omitempty"` // for M2M: column linking to target table
	SourceField       string           `json:"source_field,omitempty"`        // Scalar field holding the FK (e.g. author_id)
	Inverse           string           `json:"inverse,omitempty"`
	Endpoint          *EndpointHint    `json:"endpoint,omitempty"`
	Filters           []RelationFilter `json:"filters,omitempty"`
}

type RelationshipInfoFilter added in v0.23.0

type RelationshipInfoFilter func(resource *ResourceMetadata, relationName string, rel *RelationshipInfo) *RelationshipInfo

RelationshipInfoFilter allows callers to mutate relationship metadata prior to serialization.

type RenderMergeStrategy added in v0.28.0

type RenderMergeStrategy func(key string, viewVal, localVal any, logger Logger) (resolved any, set bool)

RenderMergeStrategy resolves collisions between view bind data and Fiber locals. The bool return controls whether the resolved value should be written.

type RequestBody added in v0.0.2

type RequestBody struct {
	Description string         `json:"description,omitempty"`
	Required    bool           `json:"required"`
	Content     map[string]any `json:"content,omitempty"`
}

RequestBody unifies the request body definitions

type RequestContext added in v0.0.2

type RequestContext interface {
	Method() string
	Path() string

	Param(name string, defaultValue ...string) string
	ParamsInt(key string, defaultValue int) int

	Query(name string, defaultValue ...string) string
	QueryValues(name string) []string
	QueryInt(name string, defaultValue int) int
	Queries() map[string]string

	Body() []byte

	Locals(key any, value ...any) any
	LocalsMerge(key any, value map[string]any) map[string]any
	Render(name string, bind any, layouts ...string) error

	Cookie(cookie *Cookie)
	Cookies(key string, defaultValue ...string) string
	CookieParser(out any) error
	Redirect(location string, status ...int) error
	RedirectToRoute(routeName string, params ViewContext, status ...int) error
	RedirectBack(fallback string, status ...int) error

	Header(string) string
	Referer() string
	OriginalURL() string

	FormFile(key string) (*multipart.FileHeader, error)
	FormValue(key string, defaultValue ...string) string

	IP() string
}

type ReservedRootClaim added in v0.53.0

type ReservedRootClaim struct {
	Owner string
	Root  string
}

type ResourceMetadata added in v0.0.3

type ResourceMetadata struct {
	// Resource identifiers
	Name         string       `json:"name"`
	PluralName   string       `json:"plural_name"`
	Description  string       `json:"description"`
	Tags         []string     `json:"tags"`
	ResourceType reflect.Type `json:"-"`

	// Routes metadata
	Routes []RouteDefinition `json:"routes"`

	// Schema information
	Schema    SchemaMetadata      `json:"schema"`
	Relations *RelationDescriptor `json:"-"`

	// Shared parameter components (referenced from routes via $ref)
	Parameters map[string]Parameter `json:"parameters,omitempty"`
}

ResourceMetadata represents collected metadata about an API resource

func GetResourceMetadata added in v0.5.0

func GetResourceMetadata(typ reflect.Type) *ResourceMetadata

type Response added in v0.0.2

type Response struct {
	Code        int            `json:"code"`
	Description string         `json:"description"`
	Headers     map[string]any `json:"headers,omitempty"`
	Content     map[string]any `json:"content,omitempty"`
}

Response unifies the response definitions

type ResponseWriter added in v0.0.2

type ResponseWriter interface {
	Status(code int) Context
	Send(body []byte) error
	SendString(body string) error
	SendStatus(code int) error
	JSON(code int, v any) error
	SendStream(r io.Reader) error
	// NoContent for status codes that shouldn't have response bodies (204, 205, 304).
	NoContent(code int) error
	SetHeader(string, string) Context
}

type Room added in v0.6.0

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

Room represents a WebSocket room with advanced features

func NewRoom added in v0.6.0

func NewRoom(id, name string, config RoomConfig, hub *WSHub) *Room

NewRoom creates a new room with the given configuration

func (*Room) AddClient added in v0.6.0

func (r *Room) AddClient(ctx context.Context, client WSClient) error

AddClient adds a client to the room

func (*Room) Broadcast added in v0.6.0

func (r *Room) Broadcast(ctx context.Context, data []byte) error

Broadcast sends a message to all clients in the room

func (*Room) BroadcastExcept added in v0.6.0

func (r *Room) BroadcastExcept(ctx context.Context, data []byte, except []string) error

BroadcastExcept sends a message to all clients except specified ones

func (*Room) BroadcastJSON added in v0.6.0

func (r *Room) BroadcastJSON(ctx context.Context, v any) error

BroadcastJSON sends JSON data to all clients in the room

func (*Room) ClearState added in v0.6.0

func (r *Room) ClearState()

ClearState clears all state

func (*Room) ClientCount added in v0.6.0

func (r *Room) ClientCount() int

ClientCount returns the number of clients in the room

func (*Room) Clients added in v0.6.0

func (r *Room) Clients() []WSClient

Clients returns all clients in the room

func (*Room) Destroy added in v0.6.0

func (r *Room) Destroy() error

Destroy destroys the room

func (*Room) Emit added in v0.6.0

func (r *Room) Emit(ctx context.Context, event string, data any) error

Emit sends an event to all clients in the room

func (*Room) EmitExcept added in v0.6.0

func (r *Room) EmitExcept(ctx context.Context, event string, data any, except []string) error

EmitExcept sends an event to all clients except specified ones

func (*Room) GetAllMetadata added in v0.6.0

func (r *Room) GetAllMetadata() map[string]any

GetAllMetadata returns all metadata

func (*Room) GetInfo added in v0.6.0

func (r *Room) GetInfo() RoomInfo

GetInfo returns public information about the room

func (*Room) GetMetadata added in v0.6.0

func (r *Room) GetMetadata(key string) any

GetMetadata gets metadata from the room

func (*Room) GetPresence added in v0.6.0

func (r *Room) GetPresence() []RoomPresence

GetPresence returns presence information for all clients in the room

func (*Room) GetState added in v0.6.0

func (r *Room) GetState(key string) any

GetState gets a value from the room's state

func (*Room) GetStateBool added in v0.6.0

func (r *Room) GetStateBool(key string) bool

GetStateBool gets a bool value from the room's state

func (*Room) GetStateInt added in v0.6.0

func (r *Room) GetStateInt(key string) int

GetStateInt gets an int value from the room's state

func (*Room) GetStateString added in v0.6.0

func (r *Room) GetStateString(key string) string

GetStateString gets a string value from the room's state

func (*Room) HasClient added in v0.6.0

func (r *Room) HasClient(clientID string) bool

HasClient checks if a client is in the room

func (*Room) ID added in v0.6.0

func (r *Room) ID() string

ID returns the room's unique identifier

func (*Room) IsDestroyed added in v0.6.0

func (r *Room) IsDestroyed() bool

IsDestroyed returns whether the room is destroyed

func (*Room) Name added in v0.6.0

func (r *Room) Name() string

Name returns the room's name

func (*Room) OnCreate added in v0.6.0

func (r *Room) OnCreate(handler RoomLifecycleHandler)

OnCreate registers a handler for when the room is created

func (*Room) OnDestroy added in v0.6.0

func (r *Room) OnDestroy(handler RoomLifecycleHandler)

OnDestroy registers a handler for when the room is destroyed

func (*Room) OnJoin added in v0.6.0

func (r *Room) OnJoin(handler RoomEventHandler)

OnJoin registers a handler for when clients join the room

func (*Room) OnLeave added in v0.6.0

func (r *Room) OnLeave(handler RoomEventHandler)

OnLeave registers a handler for when clients leave the room

func (*Room) RemoveClient added in v0.6.0

func (r *Room) RemoveClient(ctx context.Context, client WSClient) error

RemoveClient removes a client from the room

func (*Room) SetAuthFunc added in v0.6.0

func (r *Room) SetAuthFunc(authFunc RoomAuthFunc)

SetAuthFunc sets the authorization function for the room

func (*Room) SetMetadata added in v0.6.0

func (r *Room) SetMetadata(key string, value any)

SetMetadata sets metadata for the room

func (*Room) SetState added in v0.6.0

func (r *Room) SetState(key string, value any)

SetState sets a value in the room's state

func (*Room) Tags added in v0.6.0

func (r *Room) Tags() []string

Tags returns the room's tags

func (*Room) Type added in v0.6.0

func (r *Room) Type() string

Type returns the room's type

type RoomAuthFunc added in v0.6.0

type RoomAuthFunc func(ctx context.Context, room *Room, client WSClient) (bool, error)

RoomAuthFunc determines if a client can join a room

type RoomBroadcaster added in v0.6.0

type RoomBroadcaster interface {
	Emit(event string, data any) error
	EmitWithContext(ctx context.Context, event string, data any) error
	Except(clients ...WSClient) RoomBroadcaster
	Clients() []WSClient
}

RoomBroadcaster allows broadcasting to a specific room

type RoomConfig added in v0.6.0

type RoomConfig struct {
	// Maximum number of clients allowed in the room
	MaxClients int

	// Whether the room should be destroyed when empty
	DestroyWhenEmpty bool

	// Time to wait before destroying an empty room
	EmptyDestroyDelay time.Duration

	// Whether to track presence
	TrackPresence bool

	// Whether the room is private (requires authorization)
	Private bool

	// Custom room type for categorization
	Type string

	// Room tags for filtering
	Tags []string
}

RoomConfig contains configuration for a room

type RoomEventHandler added in v0.6.0

type RoomEventHandler func(ctx context.Context, room *Room, client WSClient) error

RoomEventHandler handles room join/leave events

type RoomFilter added in v0.6.0

type RoomFilter struct {
	// Filter by room type
	Type string

	// Filter by tags (any match)
	Tags []string

	// Filter by whether room is private
	Private *bool

	// Filter by minimum/maximum client count
	MinClients *int
	MaxClients *int

	// Filter by metadata key/value
	MetadataKey   string
	MetadataValue any

	// Custom filter function
	CustomFilter func(*Room) bool
}

RoomFilter defines criteria for filtering rooms

func (RoomFilter) Matches added in v0.6.0

func (f RoomFilter) Matches(room *Room) bool

Matches checks if a room matches the filter criteria

type RoomInfo added in v0.6.0

type RoomInfo struct {
	ID          string         `json:"id"`
	Name        string         `json:"name"`
	Type        string         `json:"type,omitempty"`
	Tags        []string       `json:"tags,omitempty"`
	ClientCount int            `json:"client_count"`
	MaxClients  int            `json:"max_clients"`
	CreatedAt   time.Time      `json:"created_at"`
	Metadata    map[string]any `json:"metadata,omitempty"`
	Private     bool           `json:"private"`
}

RoomInfo provides public information about a room

type RoomLifecycleHandler added in v0.6.0

type RoomLifecycleHandler func(ctx context.Context, room *Room) error

RoomLifecycleHandler handles room creation/destruction

type RoomManager added in v0.6.0

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

RoomManager manages rooms within a hub

func NewRoomManager added in v0.6.0

func NewRoomManager(hub *WSHub, config RoomManagerConfig) *RoomManager

NewRoomManager creates a new room manager

func (*RoomManager) BroadcastToRoom added in v0.6.0

func (rm *RoomManager) BroadcastToRoom(ctx context.Context, roomID string, data []byte) error

BroadcastToRoom broadcasts a message to all clients in a room

func (*RoomManager) CreateRoom added in v0.6.0

func (rm *RoomManager) CreateRoom(ctx context.Context, id, name string, config RoomConfig) (*Room, error)

CreateRoom creates a new room with the given configuration

func (*RoomManager) CreateRoomFromType added in v0.6.0

func (rm *RoomManager) CreateRoomFromType(ctx context.Context, id, name, roomType string) (*Room, error)

CreateRoomFromType creates a room using a predefined type

func (*RoomManager) EmitToRoom added in v0.6.0

func (rm *RoomManager) EmitToRoom(ctx context.Context, roomID, event string, data any) error

EmitToRoom emits an event to all clients in a room

func (*RoomManager) FindRooms added in v0.6.0

func (rm *RoomManager) FindRooms(filter RoomFilter) []*Room

FindRooms finds rooms matching the given criteria

func (*RoomManager) GetOrCreateRoom added in v0.6.0

func (rm *RoomManager) GetOrCreateRoom(ctx context.Context, id, name string, config RoomConfig) (*Room, error)

GetOrCreateRoom gets a room or creates it if it doesn't exist

func (*RoomManager) GetRoom added in v0.6.0

func (rm *RoomManager) GetRoom(id string) (*Room, error)

GetRoom retrieves a room by ID

func (*RoomManager) GetRoomPresence added in v0.6.0

func (rm *RoomManager) GetRoomPresence(roomID string) ([]RoomPresence, error)

GetRoomPresence returns presence information for a room

func (*RoomManager) JoinRoom added in v0.6.0

func (rm *RoomManager) JoinRoom(ctx context.Context, roomID string, client WSClient) error

JoinRoom adds a client to a room

func (*RoomManager) LeaveAllRooms added in v0.6.0

func (rm *RoomManager) LeaveAllRooms(ctx context.Context, client WSClient)

LeaveAllRooms removes a client from all rooms

func (*RoomManager) LeaveRoom added in v0.6.0

func (rm *RoomManager) LeaveRoom(ctx context.Context, roomID string, client WSClient) error

LeaveRoom removes a client from a room

func (*RoomManager) ListRoomInfo added in v0.6.0

func (rm *RoomManager) ListRoomInfo() []RoomInfo

ListRoomInfo returns information about all rooms

func (*RoomManager) ListRooms added in v0.6.0

func (rm *RoomManager) ListRooms() []*Room

ListRooms returns a list of all rooms

func (*RoomManager) OnRoomCreate added in v0.6.0

func (rm *RoomManager) OnRoomCreate(handler RoomLifecycleHandler)

OnRoomCreate registers a global handler for room creation

func (*RoomManager) OnRoomDestroy added in v0.6.0

func (rm *RoomManager) OnRoomDestroy(handler RoomLifecycleHandler)

OnRoomDestroy registers a global handler for room destruction

func (*RoomManager) RegisterRoomType added in v0.6.0

func (rm *RoomManager) RegisterRoomType(typeName string, config RoomConfig)

RegisterRoomType registers a predefined room type

func (*RoomManager) RemoveRoom added in v0.6.0

func (rm *RoomManager) RemoveRoom(id string) error

RemoveRoom removes a room from the manager

func (*RoomManager) Stats added in v0.6.0

func (rm *RoomManager) Stats() RoomManagerStats

Stats returns statistics about the room manager

type RoomManagerConfig added in v0.6.0

type RoomManagerConfig struct {
	// Maximum number of rooms allowed
	MaxRooms int

	// Default room configuration
	DefaultRoomConfig RoomConfig

	// Whether to allow dynamic room creation
	AllowDynamicRooms bool

	// Room naming pattern validation
	RoomNamePattern string
}

RoomManagerConfig contains configuration for the room manager

type RoomManagerStats added in v0.6.0

type RoomManagerStats struct {
	TotalRooms   int            `json:"total_rooms"`
	ActiveRooms  int            `json:"active_rooms"`
	MaxRooms     int            `json:"max_rooms"`
	TotalClients int            `json:"total_clients"`
	RoomTypes    map[string]int `json:"room_types"`
}

RoomManagerStats contains statistics about the room manager

type RoomPresence added in v0.6.0

type RoomPresence struct {
	ClientID string         `json:"client_id"`
	Username string         `json:"username,omitempty"`
	JoinedAt time.Time      `json:"joined_at"`
	Metadata map[string]any `json:"metadata,omitempty"`
}

RoomPresence tracks who's in the room

type Route added in v0.0.2

type Route[T any] struct {
	// contains filtered or unexported fields
}

func (*Route[T]) Build added in v0.0.2

func (r *Route[T]) Build() error

func (*Route[T]) DELETE added in v0.0.2

func (r *Route[T]) DELETE() *Route[T]

func (*Route[T]) Description added in v0.0.2

func (r *Route[T]) Description(description string) *Route[T]

func (*Route[T]) GET added in v0.0.2

func (r *Route[T]) GET() *Route[T]

func (*Route[T]) Handler added in v0.0.2

func (r *Route[T]) Handler(handler HandlerFunc) *Route[T]

func (*Route[T]) Method added in v0.0.2

func (r *Route[T]) Method(method HTTPMethod) *Route[T]

func (*Route[T]) Middleware added in v0.0.2

func (r *Route[T]) Middleware(middleware ...MiddlewareFunc) *Route[T]

func (*Route[T]) Name added in v0.0.2

func (r *Route[T]) Name(name string) *Route[T]

func (*Route[T]) PATCH added in v0.0.2

func (r *Route[T]) PATCH() *Route[T]

func (*Route[T]) POST added in v0.0.2

func (r *Route[T]) POST() *Route[T]

func (*Route[T]) PUT added in v0.0.2

func (r *Route[T]) PUT() *Route[T]

func (*Route[T]) Parameter added in v0.0.2

func (r *Route[T]) Parameter(name, in string, required bool, schema map[string]any) *Route[T]

func (*Route[T]) Path added in v0.0.2

func (r *Route[T]) Path(path string) *Route[T]

func (*Route[T]) RequestBody added in v0.0.2

func (r *Route[T]) RequestBody(desc string, required bool, content map[string]any) *Route[T]

func (*Route[T]) Response added in v0.0.2

func (r *Route[T]) Response(code int, desc string, content map[string]any) *Route[T]

func (*Route[T]) Responses added in v0.0.2

func (r *Route[T]) Responses(responses []Response) *Route[T]

func (*Route[T]) Summary added in v0.0.2

func (r *Route[T]) Summary(summary string) *Route[T]

func (*Route[T]) Tags added in v0.0.2

func (r *Route[T]) Tags(tags ...string) *Route[T]

type RouteBuilder added in v0.0.2

type RouteBuilder[T any] struct {
	// contains filtered or unexported fields
}

func NewRouteBuilder added in v0.0.2

func NewRouteBuilder[T any](router Router[T]) *RouteBuilder[T]

func (*RouteBuilder[T]) BuildAll added in v0.0.2

func (b *RouteBuilder[T]) BuildAll() error

func (*RouteBuilder[T]) GetMetadata added in v0.0.3

func (b *RouteBuilder[T]) GetMetadata() []RouteDefinition

func (*RouteBuilder[T]) Group added in v0.0.2

func (b *RouteBuilder[T]) Group(prefix string) *RouteBuilder[T]

Group creates a new RouteBuilder with a prefix path

func (*RouteBuilder[T]) NewRoute added in v0.0.2

func (b *RouteBuilder[T]) NewRoute() *Route[T]

NewRoute starts the configuration of a new route

type RouteDefinition added in v0.0.2

type RouteDefinition struct {
	// Core routing
	Method   HTTPMethod     `json:"method"`
	Path     string         `json:"path"`
	Name     string         `json:"name"`
	Handlers []NamedHandler `json:"-"` // Runtime only, not exported to JSON

	// metadata e.g. OpenAPI
	Summary     string       `json:"summary,omitempty"`
	Description string       `json:"description,omitempty"`
	Tags        []string     `json:"tags,omitempty"`
	Parameters  []Parameter  `json:"parameters,omitempty"`
	RequestBody *RequestBody `json:"request_body,omitempty"`
	Responses   []Response   `json:"responses,omitempty"`
	Security    []string     `json:"security,omitempty"`
	// contains filtered or unexported fields
}

RouteDefinition represents all metadata about a route, combining both runtime routing information and metadata

func NewRouteDefinition added in v0.0.3

func NewRouteDefinition() *RouteDefinition

func (*RouteDefinition) AddParameter added in v0.0.2

func (r *RouteDefinition) AddParameter(name, in string, required bool, schema map[string]any) RouteInfo

func (*RouteDefinition) AddResponse added in v0.0.2

func (r *RouteDefinition) AddResponse(code int, desc string, content map[string]any) RouteInfo

func (*RouteDefinition) AddTags added in v0.0.3

func (r *RouteDefinition) AddTags(t ...string) RouteInfo

func (*RouteDefinition) SetDescription added in v0.0.3

func (r *RouteDefinition) SetDescription(d string) RouteInfo

func (*RouteDefinition) SetName added in v0.0.3

func (r *RouteDefinition) SetName(n string) RouteInfo

func (*RouteDefinition) SetRequestBody added in v0.0.2

func (r *RouteDefinition) SetRequestBody(desc string, required bool, content map[string]any) RouteInfo

func (*RouteDefinition) SetSummary added in v0.0.3

func (r *RouteDefinition) SetSummary(s string) RouteInfo

type RouteInfo

type RouteInfo interface {
	SetName(string) RouteInfo
	SetDescription(string) RouteInfo
	SetSummary(s string) RouteInfo
	AddTags(...string) RouteInfo
	AddParameter(name, in string, required bool, schema map[string]any) RouteInfo
	SetRequestBody(desc string, required bool, content map[string]any) RouteInfo
	AddResponse(code int, desc string, content map[string]any) RouteInfo
}

type RouteManifestChange added in v0.53.0

type RouteManifestChange struct {
	Identity string             `json:"identity"`
	Before   RouteManifestEntry `json:"before"`
	After    RouteManifestEntry `json:"after"`
}

type RouteManifestDiff added in v0.53.0

type RouteManifestDiff struct {
	Added   []RouteManifestEntry  `json:"added"`
	Removed []RouteManifestEntry  `json:"removed"`
	Changed []RouteManifestChange `json:"changed"`
}

func DiffRouteManifests added in v0.53.0

func DiffRouteManifests(before, after []RouteManifestEntry) RouteManifestDiff

type RouteManifestEntry added in v0.53.0

type RouteManifestEntry struct {
	Method HTTPMethod `json:"method"`
	Path   string     `json:"path"`
	Name   string     `json:"name"`
}

func BuildRouteManifest added in v0.53.0

func BuildRouteManifest(routes []RouteDefinition) []RouteManifestEntry

func BuildRouteManifestWithInternalNames added in v0.53.0

func BuildRouteManifestWithInternalNames(routes []RouteDefinition) []RouteManifestEntry

BuildRouteManifestWithInternalNames includes runtime/helper names in the Name field. This is intended for debugging and internal router introspection rather than public API snapshots.

func BuildRouterManifest added in v0.53.0

func BuildRouterManifest(r interface{ Routes() []RouteDefinition }) []RouteManifestEntry

func BuildRouterManifestWithInternalNames added in v0.53.0

func BuildRouterManifestWithInternalNames(r interface{ Routes() []RouteDefinition }) []RouteManifestEntry

BuildRouterManifestWithInternalNames includes runtime/helper names in the Name field.

type RouteOwnershipPolicy added in v0.53.0

type RouteOwnershipPolicy struct {
	ReservedRoots   []ReservedRootClaim
	Owners          []OwnerRoutePolicy
	RouteValidation RouteValidationOptions
}

func StrictRouteOwnershipPolicy added in v0.53.0

func StrictRouteOwnershipPolicy() RouteOwnershipPolicy

type RouteValidationOptions added in v0.47.0

type RouteValidationOptions struct {
	PathConflictMode         PathConflictMode
	EnforceCatchAllConflicts bool
	EnforceRouteLints        bool
	NamedRoutePolicy         NamedRouteCollisionPolicy
}

type Router

type Router[T any] interface {
	Handle(method HTTPMethod, path string, handler HandlerFunc, middlewares ...MiddlewareFunc) RouteInfo
	Group(prefix string) Router[T]
	Mount(prefix string) Router[T]
	WithGroup(path string, cb func(r Router[T])) Router[T]
	Use(m ...MiddlewareFunc) Router[T]
	Get(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Post(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Put(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Delete(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Patch(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Head(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

	Static(prefix, root string, config ...Static) Router[T]

	// WebSocket handling
	WebSocket(path string, config WebSocketConfig, handler func(WebSocketContext) error) RouteInfo

	// TODO: Move to a different interface e.g. MetaRouter
	Routes() []RouteDefinition
	ValidateRoutes() []error
	// For debugging: Print a table of routes and their middleware chain
	PrintRoutes()
	WithLogger(logger Logger) Router[T]
}

Router represents a generic router interface

type SSEClientHandlerConfig added in v0.54.0

type SSEClientHandlerConfig struct {
	BaseRoute string
}

type SchemaMetadata added in v0.0.3

type SchemaMetadata struct {
	Required        []string                     `json:"required"`
	Name            string                       `json:"entity_name"`
	Description     string                       `json:"description"`
	LabelField      string                       `json:"label_field,omitempty"`
	Properties      map[string]PropertyInfo      `json:"properties"`
	Relationships   map[string]*RelationshipInfo `json:"relationships,omitempty"`
	RelationAliases map[string]string            `json:"relation_aliases,omitempty"`
}

func ExtractSchemaFromType added in v0.0.3

func ExtractSchemaFromType(t reflect.Type, opts ...ExtractSchemaFromTypeOptions) SchemaMetadata

ExtractSchemaFromType generates SchemaMetadata from a Go type using reflection

type SecurityRequirement added in v0.1.0

type SecurityRequirement = string

type Serializer added in v0.1.0

type Serializer interface {
	Serialize() ([]byte, error)
}

type Server

type Server[T any] interface {
	Init()
	Router() Router[T]
	WrapHandler(HandlerFunc) any
	WrappedRouter() T
	Serve(address string) error
	Shutdown(ctx context.Context) error
}

Server represents a generic server interface

func NewFiberAdapter

func NewFiberAdapter(opts ...func(*fiber.App) *fiber.App) Server[*fiber.App]

TODO: We should make this asynchronous so that we can gather options in our app before we call fiber.New (since at that point it calls init and we are done)

func NewFiberAdapterWithConfig added in v0.28.0

func NewFiberAdapterWithConfig(cfg FiberAdapterConfig, opts ...func(*fiber.App) *fiber.App) Server[*fiber.App]

NewFiberAdapterWithConfig allows callers to override adapter-level settings, including render merge strategy.

func NewHTTPServer

func NewHTTPServer(opts ...func(*httprouter.Router) *httprouter.Router) Server[*httprouter.Router]

type SimpleViewConfig added in v0.19.0

type SimpleViewConfig struct {
	DirOS      string
	DirFS      string
	Embed      bool
	Ext        string
	Reload     bool
	Debug      bool
	URLPrefix  string
	Functions  map[string]any
	AssetsDir  string
	CSSPath    string
	JSPath     string
	TemplateFS []fs.FS
}

SimpleViewConfig provides sensible defaults for file-based templates without requiring the full ViewConfigProvider surface. Assets are opt-in.

func NewSimpleViewConfig added in v0.19.0

func NewSimpleViewConfig(dirOS string) *SimpleViewConfig

NewSimpleViewConfig initializes a quick-start configuration rooted at dirOS. Asset directories are opt-in and disabled unless configured explicitly.

func NewSimpleViewConfigFS added in v0.39.0

func NewSimpleViewConfigFS(dirFS string, templates ...fs.FS) *SimpleViewConfig

NewSimpleViewConfigFS initializes a config using embedded templates.

func NewSimpleViewConfigFromModuleRoot added in v0.39.0

func NewSimpleViewConfigFromModuleRoot(dirOS string) *SimpleViewConfig

NewSimpleViewConfigFromModuleRoot resolves dirOS relative to the module root (go.mod). If module root detection fails or dirOS is already absolute, it falls back to dirOS.

func (*SimpleViewConfig) GetAssetsDir added in v0.19.0

func (c *SimpleViewConfig) GetAssetsDir() string

func (*SimpleViewConfig) GetAssetsFS added in v0.19.0

func (c *SimpleViewConfig) GetAssetsFS() fs.FS

func (*SimpleViewConfig) GetCSSPath added in v0.19.0

func (c *SimpleViewConfig) GetCSSPath() string

func (*SimpleViewConfig) GetDebug added in v0.19.0

func (c *SimpleViewConfig) GetDebug() bool

func (*SimpleViewConfig) GetDirFS added in v0.19.0

func (c *SimpleViewConfig) GetDirFS() string

func (*SimpleViewConfig) GetDirOS added in v0.19.0

func (c *SimpleViewConfig) GetDirOS() string

func (*SimpleViewConfig) GetEmbed added in v0.19.0

func (c *SimpleViewConfig) GetEmbed() bool

func (*SimpleViewConfig) GetExt added in v0.19.0

func (c *SimpleViewConfig) GetExt() string

func (*SimpleViewConfig) GetJSPath added in v0.19.0

func (c *SimpleViewConfig) GetJSPath() string

func (*SimpleViewConfig) GetReload added in v0.19.0

func (c *SimpleViewConfig) GetReload() bool

func (*SimpleViewConfig) GetTemplateFunctions added in v0.19.0

func (c *SimpleViewConfig) GetTemplateFunctions() map[string]any

func (*SimpleViewConfig) GetTemplatesFS added in v0.19.0

func (c *SimpleViewConfig) GetTemplatesFS() []fs.FS

func (*SimpleViewConfig) GetURLPrefix added in v0.19.0

func (c *SimpleViewConfig) GetURLPrefix() string

func (*SimpleViewConfig) WithAssets added in v0.19.0

func (c *SimpleViewConfig) WithAssets(dir string, cssPath string, jsPath string) *SimpleViewConfig

WithAssets enables static asset helpers using the provided root directory and optional css/js subdirectories.

func (*SimpleViewConfig) WithDebug added in v0.19.0

func (c *SimpleViewConfig) WithDebug(debug bool) *SimpleViewConfig

WithDebug toggles debug logging.

func (*SimpleViewConfig) WithEmbedFS added in v0.39.0

func (c *SimpleViewConfig) WithEmbedFS(dirFS string, templates ...fs.FS) *SimpleViewConfig

WithEmbedFS switches the config into embed mode with the provided templates.

func (*SimpleViewConfig) WithExt added in v0.19.0

func (c *SimpleViewConfig) WithExt(ext string) *SimpleViewConfig

WithExt overrides the default template extension.

func (*SimpleViewConfig) WithFunctions added in v0.19.0

func (c *SimpleViewConfig) WithFunctions(funcs map[string]any) *SimpleViewConfig

WithFunctions registers template helper functions.

func (*SimpleViewConfig) WithReload added in v0.19.0

func (c *SimpleViewConfig) WithReload(reload bool) *SimpleViewConfig

WithReload toggles template reload support.

func (*SimpleViewConfig) WithURLPrefix added in v0.19.0

func (c *SimpleViewConfig) WithURLPrefix(prefix string) *SimpleViewConfig

WithURLPrefix configures the asset URL prefix.

type Static added in v0.1.0

type Static struct {
	FS             fs.FS               // Optional filesystem implementation
	Root           string              // Root directory
	Browse         bool                // Enable directory browsing
	Index          string              // Index file (default: index.html)
	MaxAge         int                 // Max-Age for cache control header
	Download       bool                // Force download
	Compress       bool                // Enable compression
	ModifyResponse func(Context) error // Hook to modify response

}

Static configuration options

type StreamOption added in v0.41.0

type StreamOption func(*StreamOptions)

StreamOption applies stream options.

func WithContentLength added in v0.41.0

func WithContentLength(length int64) StreamOption

WithContentLength sets the content length header.

func WithExportID added in v0.41.0

func WithExportID(exportID string) StreamOption

WithExportID sets the export id response header.

func WithFilename added in v0.41.0

func WithFilename(filename string) StreamOption

WithFilename sets the download filename.

func WithFilenameSanitizer added in v0.42.0

func WithFilenameSanitizer(sanitizer FilenameSanitizer) StreamOption

WithFilenameSanitizer overrides the default filename sanitizer.

func WithMaxBufferBytes added in v0.41.0

func WithMaxBufferBytes(max int64) StreamOption

WithMaxBufferBytes sets the maximum buffer size when streaming is unavailable.

type StreamOptions added in v0.41.0

type StreamOptions struct {
	Filename          string
	ExportID          string
	ContentLength     int64
	MaxBufferBytes    int64
	FilenameSanitizer FilenameSanitizer
}

StreamOptions configures download stream responses.

func ResolveStreamOptions added in v0.41.0

func ResolveStreamOptions(opts ...StreamOption) StreamOptions

ResolveStreamOptions applies stream options.

type SubprotocolHandler added in v0.6.0

type SubprotocolHandler struct {
	Name       string
	Version    string
	Validate   func(ctx WebSocketContext) error
	Initialize func(ctx WebSocketContext) error
	OnMessage  func(ctx WebSocketContext, msgType int, data []byte) error
	OnClose    func(ctx WebSocketContext) error
}

SubprotocolHandler handles protocol-specific features

type SubprotocolNegotiator added in v0.6.0

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

SubprotocolNegotiator handles subprotocol negotiation

func NewSubprotocolNegotiator added in v0.6.0

func NewSubprotocolNegotiator() *SubprotocolNegotiator

NewSubprotocolNegotiator creates a new subprotocol negotiator

func (*SubprotocolNegotiator) GetSupportedProtocols added in v0.6.0

func (n *SubprotocolNegotiator) GetSupportedProtocols() []string

GetSupportedProtocols returns the list of supported protocols

func (*SubprotocolNegotiator) HandleConnection added in v0.6.0

func (n *SubprotocolNegotiator) HandleConnection(ctx WebSocketContext) error

HandleConnection handles a connection with the negotiated protocol

func (*SubprotocolNegotiator) NegotiateProtocol added in v0.6.0

func (n *SubprotocolNegotiator) NegotiateProtocol(requested []string) (string, *SubprotocolHandler)

NegotiateProtocol selects the best matching protocol

func (*SubprotocolNegotiator) Register added in v0.6.0

func (n *SubprotocolNegotiator) Register(handler SubprotocolHandler)

Register registers a subprotocol handler

type TypedEventHandler added in v0.6.0

type TypedEventHandler interface {
	Handle(ctx context.Context, client WSClient, event *EventMessage) error
	EventType() string
	Validate(data any) error
}

TypedEventHandler is a type-safe event handler

func TypedHandler added in v0.6.0

func TypedHandler[T any](eventType string, handler func(context.Context, WSClient, T) error) TypedEventHandler

TypedHandler creates a type-safe handler for a specific data type

type UISchemaOptions added in v0.23.0

type UISchemaOptions struct {
	EndpointDefaults  EndpointDefaultFunc                 // Optional callback to derive default endpoints.
	EndpointOverrides map[string]map[string]*EndpointHint // Overrides keyed by resource -> relation.
	RelationFilters   []RelationshipInfoFilter            // Additional filters applied before serialization.
}

UISchemaOptions configures UI-specific enrichment hooks.

type UnknownNamespaceError added in v0.51.0

type UnknownNamespaceError struct {
	Namespace string
}

UnknownNamespaceError carries namespace lookup context.

func (*UnknownNamespaceError) Error added in v0.51.0

func (e *UnknownNamespaceError) Error() string

func (*UnknownNamespaceError) Unwrap added in v0.51.0

func (e *UnknownNamespaceError) Unwrap() error

type UnknownRouteKeyError added in v0.51.0

type UnknownRouteKeyError struct {
	Namespace string
	RouteKey  string
}

UnknownRouteKeyError carries route key lookup context.

func (*UnknownRouteKeyError) Error added in v0.51.0

func (e *UnknownRouteKeyError) Error() string

func (*UnknownRouteKeyError) Unwrap added in v0.51.0

func (e *UnknownRouteKeyError) Unwrap() error

type UpgradeData added in v0.8.0

type UpgradeData map[string]any

UpgradeData stores extracted data from HTTP context before WebSocket upgrade

type ViewConfigProvider added in v0.1.0

type ViewConfigProvider interface {
	GetReload() bool
	GetDebug() bool
	GetEmbed() bool

	GetCSSPath() string
	GetJSPath() string
	GetDirFS() string
	GetDirOS() string

	GetURLPrefix() string
	GetTemplateFunctions() map[string]any

	GetExt() string

	GetAssetsFS() fs.FS
	GetAssetsDir() string
	GetTemplatesFS() []fs.FS
}

ViewConfigProvider remains the public configuration interface.

type ViewContext added in v0.1.0

type ViewContext map[string]any

ViewContext provide template values

func (ViewContext) Update added in v0.1.0

func (c ViewContext) Update(other ViewContext) ViewContext

Update updates this context with the key/value-pairs from another context.

type Views added in v0.1.0

type Views interface {
	Load() error
	Render(io.Writer, string, any, ...string) error
}

Views is the interface that wraps the Render function.

type WSAuthClaims added in v0.6.0

type WSAuthClaims interface {
	Subject() string
	UserID() string
	Role() string
	CanRead(resource string) bool
	CanEdit(resource string) bool
	CanCreate(resource string) bool
	CanDelete(resource string) bool
	HasRole(role string) bool
	IsAtLeast(minRole string) bool
}

WSAuthClaims interface for structured auth claims Compatible with go-auth AuthClaims interface

func WSAuthClaimsFromContext added in v0.6.0

func WSAuthClaimsFromContext(ctx context.Context) (WSAuthClaims, bool)

WSAuthClaimsFromContext retrieves auth claims from context

type WSAuthConfig added in v0.6.0

type WSAuthConfig struct {
	// TokenValidator is required for token validation
	TokenValidator WSTokenValidator
	// TokenExtractor defines how to extract tokens from WebSocket context
	// Supports query parameters and headers
	TokenExtractor func(ctx context.Context, client WSClient) (string, error)
	// EnableTokenCookie allows cookie-based token extraction when using the default extractor.
	EnableTokenCookie bool
	// TokenCookieNames lists cookie names to check when EnableTokenCookie is true.
	// Defaults to ["token", "auth_token"] if empty.
	TokenCookieNames []string
	// ContextEnricher enriches the context with auth claims after validation
	ContextEnricher func(ctx context.Context, claims WSAuthClaims) context.Context
	// OnAuthFailure handles authentication failures
	OnAuthFailure func(ctx context.Context, client WSClient, err error) error
	// Skip allows bypassing auth for certain connections
	Skip func(ctx context.Context, client WSClient) bool
	// Logger for auth-related logging
	Logger Logger
}

WSAuthConfig holds configuration for the WebSocket authentication middleware

type WSAuthContextKey added in v0.6.0

type WSAuthContextKey struct{}

WSAuthContextKey is used to store auth claims in context

type WSClient added in v0.6.0

type WSClient interface {
	// Core identification
	ID() string
	ConnectionID() string

	// Context support
	Context() context.Context
	SetContext(ctx context.Context)

	// Message handling
	OnMessage(handler MessageHandler) error
	OnJSON(event string, handler JSONHandler) error
	Send(data []byte) error
	SendJSON(v any) error
	SendWithContext(ctx context.Context, data []byte) error
	SendJSONWithContext(ctx context.Context, v any) error

	// Broadcasting
	Broadcast(data []byte) error
	BroadcastJSON(v any) error
	BroadcastWithContext(ctx context.Context, data []byte) error
	BroadcastJSONWithContext(ctx context.Context, v any) error

	// Room management (for Phase 2, basic interface now)
	Join(room string) error
	JoinWithContext(ctx context.Context, room string) error
	Leave(room string) error
	LeaveWithContext(ctx context.Context, room string) error
	Room(name string) RoomBroadcaster
	Rooms() []string

	// Client state management
	Set(key string, value any)
	SetWithContext(ctx context.Context, key string, value any)
	Get(key string) any
	GetString(key string) string
	GetInt(key string) int
	GetBool(key string) bool

	// Connection management
	Close(code int, reason string) error
	CloseWithContext(ctx context.Context, code int, reason string) error
	IsConnected() bool

	// Query parameters
	Query(key string, defaultValue ...string) string

	// Event emission
	Emit(event string, data any) error
	EmitWithContext(ctx context.Context, event string, data any) error

	// Low-level access when needed
	Conn() WebSocketContext
}

WSClient represents a high-level WebSocket client with automatic pump management

func NewWSClient added in v0.6.0

func NewWSClient(conn WebSocketContext, hub *WSHub) WSClient

NewWSClient creates a new WebSocket client with automatic pump management

type WSClientHandlerConfig added in v0.8.0

type WSClientHandlerConfig struct {
	BaseRoute string
	Minified  bool
	Debug     bool
}

type WSConnectionMetrics added in v0.6.0

type WSConnectionMetrics struct {
	ClientID           string        `json:"client_id"`
	RemoteAddr         string        `json:"remote_addr"`
	ConnectionStart    time.Time     `json:"connection_start"`
	ConnectionEnd      time.Time     `json:"connection_end"`
	ConnectionDuration time.Duration `json:"connection_duration"`
	Path               string        `json:"path"`
	Error              string        `json:"error,omitempty"`
}

WSConnectionMetrics represents the metrics data collected by the middleware

type WSError added in v0.6.0

type WSError struct {
	Code   int
	Reason string
}

WSError represents a WebSocket error with a close code

func (WSError) Error added in v0.6.0

func (e WSError) Error() string

Error implements the error interface

type WSErrorHandler added in v0.6.0

type WSErrorHandler func(ctx context.Context, client WSClient, err error)

WSErrorHandler handles errors with context

type WSHandler added in v0.6.0

type WSHandler func(ctx context.Context, client WSClient) error

WSHandler is a convenience type for simple WebSocket handlers

type WSHub added in v0.6.0

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

WSHub manages WebSocket connections with event-driven architecture

func NewWSHub added in v0.6.0

func NewWSHub(opts ...func(*WSHubConfig)) *WSHub

NewWSHub creates a new WebSocket hub

func (*WSHub) Broadcast added in v0.6.0

func (h *WSHub) Broadcast(data []byte) error

Broadcast sends data to all connected clients

func (*WSHub) BroadcastJSON added in v0.6.0

func (h *WSHub) BroadcastJSON(v any) error

BroadcastJSON sends JSON data to all connected clients

func (*WSHub) BroadcastJSONWithContext added in v0.6.0

func (h *WSHub) BroadcastJSONWithContext(ctx context.Context, v any) error

BroadcastJSONWithContext sends JSON data to all connected clients with context

func (*WSHub) BroadcastWithContext added in v0.6.0

func (h *WSHub) BroadcastWithContext(ctx context.Context, data []byte) error

BroadcastWithContext sends data to all connected clients with context

func (*WSHub) ClientCount added in v0.6.0

func (h *WSHub) ClientCount() int

ClientCount returns the number of connected clients

func (*WSHub) Clients added in v0.6.0

func (h *WSHub) Clients() []WSClient

Clients returns all connected clients

func (*WSHub) Close added in v0.6.0

func (h *WSHub) Close() error

Close shuts down the hub

func (*WSHub) CreateRoom added in v0.6.0

func (h *WSHub) CreateRoom(ctx context.Context, id, name string, config RoomConfig) (*Room, error)

func (*WSHub) Emit added in v0.6.0

func (h *WSHub) Emit(event string, data any) error

Emit triggers an event with data

func (*WSHub) EmitWithContext added in v0.6.0

func (h *WSHub) EmitWithContext(ctx context.Context, event string, data any) error

EmitWithContext triggers an event with context

func (*WSHub) GetRoom added in v0.6.0

func (h *WSHub) GetRoom(id string) (*Room, error)

func (*WSHub) Handler added in v0.6.0

func (h *WSHub) Handler() func(Context) error

Handler returns an HTTP handler for WebSocket connections

func (*WSHub) ListRooms added in v0.6.0

func (h *WSHub) ListRooms() []RoomInfo

func (*WSHub) On added in v0.6.0

func (h *WSHub) On(event string, handler EventHandler) error

On registers an event handler

func (*WSHub) OnConnect added in v0.6.0

func (h *WSHub) OnConnect(handler EventHandler) error

OnConnect registers a handler for client connections

func (*WSHub) OnDisconnect added in v0.6.0

func (h *WSHub) OnDisconnect(handler EventHandler) error

OnDisconnect registers a handler for client disconnections

func (*WSHub) OnError added in v0.6.0

func (h *WSHub) OnError(handler WSErrorHandler) error

OnError registers an error handler

func (*WSHub) Room added in v0.6.0

func (h *WSHub) Room(name string) RoomBroadcaster

Room returns a room broadcaster

func (*WSHub) RoomStats added in v0.6.0

func (h *WSHub) RoomStats() RoomManagerStats

type WSHubConfig added in v0.6.0

type WSHubConfig struct {
	// Maximum message size in bytes
	MaxMessageSize int64

	// Connection timeouts
	HandshakeTimeout time.Duration
	ReadTimeout      time.Duration
	WriteTimeout     time.Duration

	// Ping/Pong configuration
	PingPeriod time.Duration
	PongWait   time.Duration

	// Buffer sizes
	ReadBufferSize  int
	WriteBufferSize int

	// Enable compression
	EnableCompression bool
}

WSHubConfig contains configuration for the WebSocket hub

func DefaultWSHubConfig added in v0.6.0

func DefaultWSHubConfig() WSHubConfig

DefaultWSHubConfig returns default configuration

type WSInMemoryRateLimitStore added in v0.6.0

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

WSInMemoryRateLimitStore provides an in-memory implementation of WSRateLimitStore

func NewWSInMemoryRateLimitStore added in v0.6.0

func NewWSInMemoryRateLimitStore(rateLimit rate.Limit, burstLimit int) *WSInMemoryRateLimitStore

NewWSInMemoryRateLimitStore creates a new in-memory rate limit store

func (*WSInMemoryRateLimitStore) CleanupExpired added in v0.6.0

func (s *WSInMemoryRateLimitStore) CleanupExpired()

func (*WSInMemoryRateLimitStore) Close added in v0.6.0

func (s *WSInMemoryRateLimitStore) Close()

Close stops the cleanup goroutine

func (*WSInMemoryRateLimitStore) GetLimiter added in v0.6.0

func (s *WSInMemoryRateLimitStore) GetLimiter(clientID string) *rate.Limiter

type WSLoggerConfig added in v0.6.0

type WSLoggerConfig struct {
	// Logger is the logger instance.
	Logger Logger
	// Skip allows skipping the middleware based on the WebSocket context.
	Skip func(c WebSocketContext) bool
	// Formatter is a function to format the log string.
	Formatter func(WSClient, time.Time, time.Time) string
}

WSLoggerConfig holds configuration for the WebSocket logging middleware

type WSMetricsConfig added in v0.6.0

type WSMetricsConfig struct {
	// Sink is the metrics sink where collected metrics will be sent
	Sink WSMetricsSink
	// Skip allows skipping the middleware based on the WebSocket context
	Skip func(c WebSocketContext) bool
}

WSMetricsConfig holds configuration for the WebSocket metrics middleware

type WSMetricsSink added in v0.6.0

type WSMetricsSink interface {
	// RecordConnection is called when a WebSocket connection completes
	RecordConnection(metrics WSConnectionMetrics)
}

WSMetricsSink defines the interface for metrics collection

type WSRateLimitConfig added in v0.6.0

type WSRateLimitConfig struct {
	// Store is the rate limit data store
	Store WSRateLimitStore
	// Skip allows skipping the middleware based on the WebSocket context
	Skip func(c WebSocketContext) bool
	// KeyFunc extracts the rate limit key from the client (defaults to client ID)
	KeyFunc func(client WSClient) string
	// OnRateLimited is called when a client is rate limited
	OnRateLimited func(client WSClient)
}

WSRateLimitConfig holds configuration for the WebSocket rate limiting middleware

type WSRateLimitStore added in v0.6.0

type WSRateLimitStore interface {
	// GetLimiter returns a rate limiter for the given client identifier
	GetLimiter(clientID string) *rate.Limiter
	// CleanupExpired removes expired limiters to prevent memory leaks
	CleanupExpired()
}

WSRateLimitStore defines the interface for storing rate limit data

type WSRecoverConfig added in v0.6.0

type WSRecoverConfig struct {
	// Logger is the logger instance.
	Logger Logger
	// Skip allows skipping the middleware based on the WebSocket context.
	Skip func(c WebSocketContext) bool
	// StackSize sets the buffer size for capturing stack traces (default: 4KB)
	StackSize int
	// EnableStackTrace determines if stack traces should be logged (default: true)
	EnableStackTrace bool
}

WSRecoverConfig holds configuration for the WebSocket panic recovery middleware

type WSTokenIDer added in v0.45.0

type WSTokenIDer interface {
	TokenID() string
}

WSTokenIDer is an optional interface for auth claims that expose a token ID.

type WSTokenValidator added in v0.6.0

type WSTokenValidator interface {
	Validate(tokenString string) (WSAuthClaims, error)
}

WSTokenValidator interface for WebSocket authentication Mirrors the go-auth TokenService.Validate method signature

type WebSocketConfig added in v0.6.0

type WebSocketConfig struct {
	// Origin validation
	Origins     []string
	CheckOrigin func(origin string) bool

	// Protocol negotiation
	Subprotocols []string

	// Buffer sizes
	ReadBufferSize  int
	WriteBufferSize int

	// Timeouts and Keep-Alive Configuration
	//
	// HandshakeTimeout: Maximum time allowed for the WebSocket handshake to complete.
	// If the client doesn't complete the handshake within this time, the connection
	// is rejected. Default: 10 seconds.
	HandshakeTimeout time.Duration

	// ReadTimeout: Maximum time to wait when reading from the WebSocket connection.
	// If no data is received within this time, the connection is considered dead
	// and will be closed. This prevents hanging connections that never send data.
	// Set to 0 to disable read timeout. Default: 60 seconds.
	ReadTimeout time.Duration

	// WriteTimeout: Maximum time allowed for write operations to the WebSocket.
	// If a write operation (like sending a message) takes longer than this,
	// it will timeout and the connection may be closed. Default: 10 seconds.
	WriteTimeout time.Duration

	// PingPeriod: How often to send ping frames to the client to check if the
	// connection is still alive. Must be less than PongWait. The server sends
	// ping frames at this interval to detect broken connections. Default: 54 seconds.
	// Set to 0 to disable automatic pings.
	PingPeriod time.Duration

	// PongWait: Maximum time to wait for a pong response after sending a ping.
	// If the client doesn't respond with a pong within this time after receiving
	// a ping, the connection is considered dead and will be closed. This is the
	// primary mechanism for detecting broken connections. Default: 60 seconds.
	// Must be greater than PingPeriod.
	PongWait time.Duration

	// Message limits
	MaxMessageSize int64

	// Compression
	EnableCompression bool
	CompressionLevel  int

	// Connection management
	AllowMultipleConnections bool
	ConnectionPoolSize       int

	// Event handlers
	OnConnect    func(WebSocketContext) error
	OnDisconnect func(WebSocketContext, error)
	OnMessage    func(WebSocketContext, int, []byte) error
	OnError      func(WebSocketContext, error)
	OnPreUpgrade func(Context) (UpgradeData, error)

	// Custom upgrader (adapter-specific)
	CustomUpgrader any

	// Metrics and monitoring
	EnableMetrics bool
	MetricsPrefix string
}

WebSocketConfig contains configuration options for WebSocket connections

func DefaultWebSocketConfig added in v0.6.0

func DefaultWebSocketConfig() WebSocketConfig

DefaultWebSocketConfig returns a WebSocketConfig with sensible defaults that prevent common WebSocket issues like hanging connections and resource leaks.

Key timeout defaults prevent connection issues:

  • ReadTimeout (60s): Prevents handlers from blocking indefinitely on dead connections
  • WriteTimeout (10s): Ensures write operations don't hang the server
  • PingPeriod (54s) + PongWait (60s): Automatic connection health checking
  • HandshakeTimeout (10s): Prevents slow handshake attacks

These defaults ensure that:

  1. Dead connections are detected and cleaned up automatically
  2. Server resources (goroutines, memory, locks) are released properly
  3. APIs and endpoints don't hang due to zombie WebSocket connections
  4. The server remains responsive under load

func (*WebSocketConfig) ApplyDefaults added in v0.6.0

func (c *WebSocketConfig) ApplyDefaults()

ApplyDefaults fills in any zero values with sensible defaults

func (*WebSocketConfig) Validate added in v0.6.0

func (c *WebSocketConfig) Validate() error

Validate checks the WebSocketConfig for common configuration errors

type WebSocketContext added in v0.6.0

type WebSocketContext interface {
	Context

	// Connection state
	IsWebSocket() bool
	WebSocketUpgrade() error

	// Message operations
	WriteMessage(messageType int, data []byte) error
	ReadMessage() (messageType int, p []byte, err error)
	WriteJSON(v any) error
	ReadJSON(v any) error
	WritePing(data []byte) error
	WritePong(data []byte) error

	// Connection management
	Close() error
	CloseWithStatus(code int, reason string) error
	SetReadDeadline(t time.Time) error
	SetWriteDeadline(t time.Time) error
	SetPingHandler(handler func(data []byte) error)
	SetPongHandler(handler func(data []byte) error)
	SetCloseHandler(handler func(code int, text string) error)

	// WebSocket-specific headers/info
	Subprotocol() string
	Extensions() []string
	RemoteAddr() string
	LocalAddr() string

	// Connection properties
	IsConnected() bool
	ConnectionID() string

	// Pre-upgrade data access
	UpgradeData(key string) (any, bool)
}

WebSocketContext extends Context for WebSocket operations

type WebSocketContextFactory added in v0.6.0

type WebSocketContextFactory interface {
	CreateWebSocketContext(c Context, config WebSocketConfig) (WebSocketContext, error)
	SupportsWebSocket() bool
	AdapterName() string
}

WebSocketContextFactory interface for creating adapter-specific WebSocket contexts

func GetFiberWebSocketFactory added in v0.6.0

func GetFiberWebSocketFactory() WebSocketContextFactory

GetFiberWebSocketFactory returns the Fiber WebSocket factory

func GetGlobalWebSocketFactory added in v0.6.0

func GetGlobalWebSocketFactory(adapterName string) WebSocketContextFactory

GetGlobalWebSocketFactory gets a factory by adapter name from global registry

func GetHTTPRouterWebSocketFactory added in v0.6.0

func GetHTTPRouterWebSocketFactory() WebSocketContextFactory

GetHTTPRouterWebSocketFactory returns the HTTPRouter WebSocket factory

func GetWebSocketFactoryByContext added in v0.6.0

func GetWebSocketFactoryByContext(c Context) WebSocketContextFactory

GetWebSocketFactoryByContext attempts to find a factory for the given context

type WebSocketContextWrapper added in v0.6.0

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

WebSocketContextWrapper provides common functionality for WebSocket contexts

func NewWebSocketContextWrapper added in v0.6.0

func NewWebSocketContextWrapper(baseContext Context, config WebSocketConfig, protocol string) *WebSocketContextWrapper

NewWebSocketContextWrapper creates a new WebSocket context wrapper

func (*WebSocketContextWrapper) BaseContext added in v0.6.0

func (w *WebSocketContextWrapper) BaseContext() Context

BaseContext returns the underlying context

func (*WebSocketContextWrapper) Config added in v0.6.0

Config returns the WebSocket configuration

func (*WebSocketContextWrapper) ConnectionID added in v0.6.0

func (w *WebSocketContextWrapper) ConnectionID() string

ConnectionID returns the unique connection ID

func (*WebSocketContextWrapper) IsConnected added in v0.6.0

func (w *WebSocketContextWrapper) IsConnected() bool

IsConnected returns the connection status

func (*WebSocketContextWrapper) SetConnected added in v0.6.0

func (w *WebSocketContextWrapper) SetConnected(connected bool)

SetConnected updates the connection status

func (*WebSocketContextWrapper) Subprotocol added in v0.6.0

func (w *WebSocketContextWrapper) Subprotocol() string

Subprotocol returns the negotiated subprotocol

type WebSocketFactoryConfig added in v0.6.0

type WebSocketFactoryConfig struct {
	EnableMetrics     bool
	MetricsPrefix     string
	DefaultBufferSize int
	ConnectionTimeout int
	MaxConnections    int
	EnableCompression bool
}

WebSocketFactoryConfig provides configuration for WebSocket factories

func DefaultWebSocketFactoryConfig added in v0.6.0

func DefaultWebSocketFactoryConfig() WebSocketFactoryConfig

DefaultWebSocketFactoryConfig returns default factory configuration

type WebSocketFactoryError added in v0.6.0

type WebSocketFactoryError struct {
	AdapterName string
	Operation   string
	Err         error
}

WebSocketFactoryError represents errors that occur during factory operations

func NewWebSocketFactoryError added in v0.6.0

func NewWebSocketFactoryError(adapterName, operation string, err error) *WebSocketFactoryError

NewWebSocketFactoryError creates a new factory error

func (*WebSocketFactoryError) Error added in v0.6.0

func (e *WebSocketFactoryError) Error() string

Error implements the error interface

func (*WebSocketFactoryError) Unwrap added in v0.6.0

func (e *WebSocketFactoryError) Unwrap() error

Unwrap returns the underlying error

type WebSocketFactoryRegistry added in v0.6.0

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

WebSocketFactoryRegistry manages WebSocket context factories

func NewWebSocketFactoryRegistry added in v0.6.0

func NewWebSocketFactoryRegistry() *WebSocketFactoryRegistry

NewWebSocketFactoryRegistry creates a new factory registry

func (*WebSocketFactoryRegistry) Get added in v0.6.0

Get retrieves a factory by adapter name

func (*WebSocketFactoryRegistry) GetByContext added in v0.6.0

GetByContext attempts to determine the appropriate factory based on context type

func (*WebSocketFactoryRegistry) List added in v0.6.0

func (r *WebSocketFactoryRegistry) List() []string

List returns all registered adapter names

func (*WebSocketFactoryRegistry) Register added in v0.6.0

func (r *WebSocketFactoryRegistry) Register(adapterName string, factory WebSocketContextFactory)

Register adds a factory to the registry

type WebSocketMiddleware added in v0.6.0

type WebSocketMiddleware func(next WSHandler) WSHandler

WebSocketMiddleware represents middleware for WebSocket connections

func ChainWSMiddleware added in v0.6.0

func ChainWSMiddleware(middlewares ...WebSocketMiddleware) WebSocketMiddleware

ChainWSMiddleware chains multiple WebSocket middlewares. Middleware is executed in an "outside-in" order, meaning the first middleware in the list becomes the outermost layer and will be executed first on the way in and last on the way out. For example: ChainWSMiddleware(WSRecover(), WSLogger(), WSAuth(), ...) will execute WSRecover first, then WSLogger, then WSAuth when processing a request.

func NewWSAuth added in v0.6.0

func NewWSAuth(config ...WSAuthConfig) WebSocketMiddleware

NewWSAuth creates a new WebSocket authentication middleware

func NewWSLogger added in v0.6.0

func NewWSLogger(config ...WSLoggerConfig) WebSocketMiddleware

NewWSLogger returns a WebSocket logging middleware with the specified configuration

func NewWSMetrics added in v0.6.0

func NewWSMetrics(config ...WSMetricsConfig) WebSocketMiddleware

NewWSMetrics returns a WebSocket metrics middleware with the specified configuration

func NewWSRateLimit added in v0.6.0

func NewWSRateLimit(config ...WSRateLimitConfig) WebSocketMiddleware

NewWSRateLimit returns a WebSocket rate limiting middleware with the specified configuration

func NewWSRecover added in v0.6.0

func NewWSRecover(config ...WSRecoverConfig) WebSocketMiddleware

NewWSRecover returns a WebSocket panic recovery middleware with the specified configuration

type WebSocketSecurityError added in v0.6.0

type WebSocketSecurityError struct {
	Code    string
	Message string
}

WebSocketSecurityError represents a security validation error

func NewWebSocketSecurityError added in v0.6.0

func NewWebSocketSecurityError(code, message string) *WebSocketSecurityError

NewWebSocketSecurityError creates a new security error

func (*WebSocketSecurityError) Error added in v0.6.0

func (e *WebSocketSecurityError) Error() string

Error implements the error interface

type WebSocketSecurityPolicy added in v0.6.0

type WebSocketSecurityPolicy struct {
	// Origin validation
	AllowedOrigins      []string
	DisallowedOrigins   []string
	RequireOriginHeader bool
	SameOriginOnly      bool
	CustomOriginChecker func(origin string) bool

	// Protocol validation
	AllowedProtocols      []string
	DisallowedProtocols   []string
	CustomProtocolChecker func(protocol string) bool

	// Header validation
	RequiredHeaders       map[string]string
	DisallowedHeaders     []string
	CustomHeaderValidator func(headers map[string]string) bool

	// Rate limiting
	EnableRateLimit     bool
	MaxConnectionsPerIP int
	ConnectionRateLimit int // connections per minute

	// Security features
	RequireSecureOrigin  bool // Only allow HTTPS origins
	AllowLocalhostOrigin bool // Allow localhost for development
	StrictHostValidation bool // Validate Host header matches expected values
	AllowedHosts         []string
}

WebSocketSecurityPolicy defines security policies for WebSocket connections

func DefaultWebSocketSecurityPolicy added in v0.6.0

func DefaultWebSocketSecurityPolicy() WebSocketSecurityPolicy

DefaultWebSocketSecurityPolicy returns a secure default policy

func ProductionWebSocketSecurityPolicy added in v0.6.0

func ProductionWebSocketSecurityPolicy() WebSocketSecurityPolicy

ProductionWebSocketSecurityPolicy returns a strict security policy for production

Directories

Path Synopsis
Package eventstream provides a transport-neutral runtime event stream surface for go-router.
Package eventstream provides a transport-neutral runtime event stream surface for go-router.
examples
router command
middleware
featuregate
Package featuregate provides go-router middleware for wiring go-featuregate scope and actor data into request contexts.
Package featuregate provides go-router middleware for wiring go-featuregate scope and actor data into request contexts.
Package ssefiber provides Fiber-first SSE route helpers backed by the transport-neutral eventstream package.
Package ssefiber provides Fiber-first SSE route helpers backed by the transport-neutral eventstream package.

Jump to

Keyboard shortcuts

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