-
Notifications
You must be signed in to change notification settings - Fork 0
Getting Started
go get github.com/kryovyx/rexpackage main
import (
"time"
"github.com/kryovyx/rex"
"github.com/kryovyx/rex/logger"
"github.com/kryovyx/rex/route"
)
type UserService struct{}
func (s *UserService) Greet(name string) string { return "Hello, " + name }
func main() {
app := rex.New(
rex.WithConfig(&rex.Config{
DefaultRouter: rex.RouterConfig{Addr: ":8080"},
ShutdownTimeout: 30 * time.Second,
}),
rex.WithLogLevel(logger.LogLevelDebug),
)
// Dependencies
if err := app.Container().Singleton(func() *UserService {
return &UserService{}
}); err != nil {
panic(err)
}
// Routes
if err := app.RegisterRoute(route.New("GET", "/", func(ctx route.Context) {
_ = ctx.JSON(200, map[string]string{"message": "Welcome to Rex"})
})); err != nil {
panic(err)
}
if err := app.RegisterRoute(route.New("GET", "/greet/{name}", func(ctx route.Context) {
var svc *UserService
if err := ctx.Resolver().Resolve(&svc); err != nil {
_ = ctx.JSON(500, map[string]string{"error": "unavailable"})
return
}
_ = ctx.Text(200, svc.Greet(ctx.Param("name")))
})); err != nil {
panic(err)
}
if err := app.Run(); err != nil {
panic(err)
}
}$ curl localhost:8080/greet/ada
Hello, ada
RegisterRoute, RegisterRouteToRouter and CreateRouter all return errors,
and discarding them is the most common way to lose a route silently. A typo'd
path, a missing handler, a duplicate registration or an unknown router name is
rejected — and if you ignore the return value, the route simply never appears
and the 404 is a mystery.
If the if err := noise bothers you, batch it:
if err := errors.Join(
app.RegisterRoute(route.New("GET", "/users", listUsers)),
app.RegisterRoute(route.New("POST", "/users", createUser)),
app.RegisterRoute(route.New("GET", "/users/{id}", getUser)),
); err != nil {
return fmt.Errorf("routes: %w", err)
}All equivalent; pick one and be consistent.
// Options to New.
app := rex.New(rex.WithConfig(cfg), rex.WithLogLevel(logger.LogLevelDebug))
// Fluent.
app := rex.New().
WithOptions(rex.WithConfig(cfg)).
WithLogger(logger.NewSlogLoggerWithLevel(logger.LogLevelDebug))
// After the fact — still fine, because nothing is built until Run.
app := rex.New()
app.WithOptions(rex.WithConfig(cfg))import (
"github.com/kryovyx/rex"
health "github.com/kryovyx/rextension-health"
metric "github.com/kryovyx/rextension-metric"
)
app := rex.New(
health.WithHealth(nil), // /healthz, /readyz on a dedicated listener
metric.WithMetrics(nil), // /metrics, plus request instrumentation
)Extensions declare their own routes, routers and middleware during Run. Order
of registration does not matter — middleware order comes from the
priority scale, not from argument order.
Run blocks until SIGINT, SIGTERM or Stop(). RunContext adds a fourth
exit: cancelling the context.
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
if err := app.RunContext(ctx); err != nil {
log.Fatal(err)
}The router is an http.Handler, so after Run you can drive it directly — but
Run blocks, so tests usually start it in a goroutine and use Stop:
func TestGreet(t *testing.T) {
app := rex.New(rex.WithConfig(&rex.Config{
DefaultRouter: rex.RouterConfig{Addr: "127.0.0.1:0"}, // any free port
}))
if err := app.RegisterRoute(route.New("GET", "/greet/{name}", greet)); err != nil {
t.Fatal(err)
}
errCh := make(chan error, 1)
go func() { errCh <- app.Run() }()
t.Cleanup(func() {
_ = app.Stop()
if err := <-errCh; err != nil {
t.Errorf("run: %v", err)
}
})
// app.Routers()["default"].Addr() is the bound address.
}Addr: "127.0.0.1:0" binds a free port, and Router.Addr() reports the one
actually bound — so parallel tests do not collide.
Stop() on an instance that was never Run is safe and returns immediately.
-
Lifecycle — what happens between
Newand the first request - Routing — parameters, wildcards, 404 vs 405
- Configuration — every field, and what its default protects you from
rex — Restful Extended eXperience · MIT · © 2026 Kryovyx · pre-1.0 (alpha), interfaces may change
Getting started
Core
Operating
Ecosystem