// Package web provides the HTTP foundation for Einherjar services. // // The root package exposes [New] — a factory that returns a lifecycle-managed // chi server with the recommended middleware stack pre-applied (request ID, // panic recovery, request logging). Import the sub-packages directly for full // control over individual components. // // Sub-packages: // // - [code.nochebuena.dev/einherjar/web/server] — lifecycle-managed chi HTTP server // - [code.nochebuena.dev/einherjar/web/mw] — transport middleware: recover, CORS, request ID, request logger, rate limiting // - [code.nochebuena.dev/einherjar/web/httputil] — typed handler adapters and HTTP response helpers // - [code.nochebuena.dev/einherjar/web/health] — concurrent health check handler // // # Choosing web.New vs server.New // // Two tiers over the same underlying server: // // - [New] (web.New) — batteries-included. The recommended middleware stack is wired // for you; CORS uses explicit origins from EINHERJAR_SERVER_CORS_ORIGINS. Use it for // most services. It does NOT support allow-all CORS. // - [code.nochebuena.dev/einherjar/web/server.New] — full control. You compose the // middleware list yourself. Use it when you need a custom middleware order, a custom // request-ID generator, or allow-all CORS in development ([mw.CORSAllowAll], gated by // environment). // // # web.New — batteries included (explicit CORS origins) // // logger := logz.New(logz.Config{JSON: true}) // lc := launcher.New(logger) // // // CORS from EINHERJAR_SERVER_CORS_ORIGINS (explicit origins; empty ⇒ CORS off + log). // srv := web.New(logger, web.Config{Server: cfg.Server}) // srv.Get("/health", health.NewHandler(logger, db, cache).ServeHTTP) // // lc.Append(srv) // if err := lc.Run(); err != nil { // logger.Error("launcher failed", err) // os.Exit(1) // } // // # server.New — full control (allow-all CORS in dev) // // For allow-all CORS in local development, gate it by environment and compose the // stack yourself. mw.CORS panics on "*", so allow-all is [mw.CORSAllowAll], never a // "*" in the origins list: // // var corsMW func(http.Handler) http.Handler // if strings.EqualFold(cfg.AppEnv, "local") { // corsMW = mw.CORSAllowAll() // dev: any origin // } else { // corsMW = mw.CORS(cfg.Server.CORSOrigins) // prod: explicit origins from env // } // srv := server.New(logger, cfg.Server, server.WithMiddleware( // mw.Recover(logger), mw.RequestID(uuid.NewString), corsMW, mw.RequestLogger(logger), // )) package web