-
Notifications
You must be signed in to change notification settings - Fork 0
Home
rextension is the module every Rex extension depends on instead of the
framework. It declares the interfaces, and nothing implements them here.
go get github.com/kryovyx/rextensionRequires Go 1.27+. It has one dependency, encoding/json/v2 support in the
standard library, and imports nothing from this ecosystem.
| Module | Contains | Depends on |
|---|---|---|
rextension |
interfaces and contracts | nothing |
rex |
the framework implementation |
rextension, dix
|
dix |
the DI container implementation | nothing |
rextension-* |
extensions | rextension only |
An extension that imported rex would drag the whole framework — router, event
bus, logger, container — into every consumer, and would be recompiled by every
change to any of it. Depending on the contract instead means an extension's
module graph is one line long, and a change to rex internals cannot reach it.
rex re-exports the types declared here as aliases (rex.Extension is
rextension.Extension), so application code that only imports rex never
notices the split.
Lifecycle — Extension with five hooks;
RouteValidator for a startup check over the whole route
table.
Framework access — Rex: logger, container, event bus,
route registration, router creation, four flavours of middleware registration.
Middleware — Middleware, PerRouteMiddleware,
PerRouterMiddleware, and the fixed
priority scale that orders the chain.
Routes — Route,
RouteInfo,
BodySchema,
BodyLimitedRoute.
Errors on the wire — Problem, the RFC 9457 document
every extension in the ecosystem answers with.
Security — SecuritySchemeAccessor,
SecuredRouteAccessor,
SchemeRegistry and the optional
capability interfaces, so the security and OpenAPI extensions cooperate without
importing each other.
Browser origins — OriginPolicy, written once and read by
both CORS and CSRF.
DI — Container, Resolver, Scope, re-exported
from rextension/di.
Events — the EventBus and the typed router events.
package myext
import (
"context"
rx "github.com/kryovyx/rextension"
)
type Extension struct{}
func New() rx.Extension { return &Extension{} }
// The idiomatic entry point: an Option, so the application writes
// rex.New(myext.With()).
func With() rx.Option { return rx.WithExtension(New()) }
func (e *Extension) OnInitialize(ctx context.Context, r rx.Rex) error {
r.Logger().Info("myext initialising")
return nil
}
func (e *Extension) OnStart(ctx context.Context, r rx.Rex) error { return nil }
func (e *Extension) OnReady(ctx context.Context, r rx.Rex) error { return nil }
func (e *Extension) OnStop(ctx context.Context, r rx.Rex) error { return nil }
func (e *Extension) OnShutdown(ctx context.Context, r rx.Rex) error { return nil }Read Writing an Extension next — it covers the parts
that are not obvious from the interface: where to register routes, why never to
register from OnReady, and how to attach middleware to only the routes you
apply to.
Declare before Run; the route table is built once and then frozen.
Extensions declare routes, routers and middleware in OnInitialize and
OnStart. The framework then builds every router's route table, composes every
middleware chain, validates, and only then binds the listeners. After that the
table is immutable and served without locking — so a route registered from
OnReady is refused with ErrRouterFrozen, not silently dropped.
Everything else in this module follows from that: per-route middleware is a
factory consulted at build time, RouteInfo carries the router name because
build time is when that mapping is known, and RouteValidator runs at exactly
the moment the whole table exists and no socket is open yet.
rextension — the Rex extension contract · MIT · © 2026 Kryovyx · pre-1.0, interfaces may change
Building an extension
Contracts
Reference
Ecosystem