• v1.0.2 9b6608418b

    Rene Nochebuena released this 2026-05-11 22:18:25 -06:00 | 0 commits to main since this release

    v1.0.2

    code.nochebuena.dev/go/httpserver

    Overview

    httpserver v1.0.2 commits the HTTP server API as stable and adds configurable
    graceful-shutdown timeout. The module wraps chi's router in a launcher.Component
    lifecycle with synchronous port binding, guard against nil server on stop, and a
    duck-typed Logger interface satisfied by logz.Logger.

    What Changed Since v0.9.2

    Configurable ShutdownTimeout

    Config gains a ShutdownTimeout time.Duration field (SERVER_SHUTDOWN_TIMEOUT,
    default 10s). Previously the graceful-shutdown deadline was hardcoded to 10 seconds.
    Callers serving long-running requests (file uploads, streaming) or preferring a shorter
    fail-fast window can now set this per environment without code changes.

    // Default: 10s — no change required for existing deployments
    cfg := httpserver.Config{}
    
    // Override via env or struct literal
    cfg.ShutdownTimeout = 30 * time.Second
    

    Dependency bumps

    launcher and logz promoted to v1.0.1. go directive updated to 1.26.

    Full API (stable)

    ConfigHost, Port, ReadTimeout, WriteTimeout, IdleTimeout,
    ShutdownTimeout; all settable via SERVER_* environment variables.

    Logger — duck-typed: Info(msg string, args ...any), Error(msg string, err error, args ...any).

    Option — functional option type.

    WithMiddleware(mw ...func(http.Handler) http.Handler) Option — accumulates middleware
    applied to the router during OnInit; order preserved; multiple calls append.

    HttpServerComponent — embeds launcher.Component and chi.Router; callers get the
    full chi routing API (Get, Post, Route, Mount, Use, With, Group, etc.) on
    the same value that participates in the launcher lifecycle.

    New(logger Logger, cfg Config, opts ...Option) HttpServerComponent — constructor;
    no middleware installed by default.

    Migration from v0.9.2

    No breaking changes. ShutdownTimeout defaults to 10s — existing deployments behave
    identically without any config change.

    go get code.nochebuena.dev/go/httpserver@v1.0.2
    
    Downloads
  • v0.9.2 1801754a9b

    Rene Nochebuena released this 2026-03-24 18:53:56 -06:00 | 1 commits to main since this release

    v0.9.2

    code.nochebuena.dev/go/httpserver

    Overview

    Patch release. Fixes a silent failure in OnStart where a port-in-use error was
    swallowed inside a goroutine, leaving the application running without an HTTP server
    instead of failing fast.

    What's Changed

    Fixed

    • OnStart now binds the TCP listener synchronously via net.Listen before
      launching the serve goroutine. A port-in-use (or any other bind) error is
      returned immediately from OnStart, allowing the launcher to treat it as a
      fatal startup failure and trigger a clean shutdown. Previously the error only
      appeared in a log line while the application continued running without an
      HTTP server.

    Installation

    go get code.nochebuena.dev/go/httpserver@v0.9.2
    

    Requires code.nochebuena.dev/go/launcher and github.com/go-chi/chi/v5.

    Full Changelog

    https://code.nochebuena.dev/go/httpserver/compare/v0.9.1...v0.9.2

    Downloads
  • v0.9.1 69cea64ea0

    Rene Nochebuena released this 2026-03-21 10:53:55 -06:00 | 3 commits to main since this release

    v0.9.1

    code.nochebuena.dev/go/httpserver

    Overview

    Patch release. Fixes a nil pointer panic in OnStop that occurred when the launcher
    called cleanup on an httpserver component whose OnStart had never run — typically
    because an earlier component (e.g. the database) failed during startup.

    What's Fixed

    OnStop nil guard

    s.srv (the *http.Server) is assigned only inside OnStart. In v0.9.0, OnStop
    called s.srv.Shutdown(ctx) unconditionally, panicking with a nil pointer dereference
    whenever the launcher triggered cleanup before OnStart had executed.

    v0.9.1 adds an early return:

    func (s *httpServer) OnStop() error {
        if s.srv == nil {
            return nil
        }
        ...
    }
    

    No interfaces, configuration, or public API are changed.

    Upgrade

    go get code.nochebuena.dev/go/httpserver@v0.9.1
    

    Requires no code changes. Drop-in replacement for v0.9.0.


    v0.9.0

    code.nochebuena.dev/go/httpserver

    Overview

    httpserver provides a lifecycle-managed HTTP server built on chi v5. It implements
    launcher.Component (OnInit → OnStart → OnStop) and embeds chi.Router directly,
    so a single value serves both as a lifecycle component and as the router for all route
    registration.

    This release reflects an API designed through multiple architecture reviews and
    validated end-to-end via the todo-api POC. It is versioned at v0.9.0 rather than
    v1.0.0 because it has not yet been exercised in production workloads across all edge
    cases, preserving the option for minor API refinements before committing to full
    stability.

    What's Included

    New(logger Logger, cfg Config, opts ...Option) HttpServerComponent

    Constructs the server component. No middleware is installed by default; the full
    middleware stack is composed explicitly at construction time via WithMiddleware.

    HttpServerComponent interface

    Embeds both launcher.Component and chi.Router, giving callers the complete chi
    routing API (Get, Post, Route, Mount, Use, With, Group, etc.) on the
    same value that participates in the launcher lifecycle.

    Config struct

    Field Env var Default
    Host SERVER_HOST 0.0.0.0
    Port SERVER_PORT 8080
    ReadTimeout SERVER_READ_TIMEOUT 5s
    WriteTimeout SERVER_WRITE_TIMEOUT 10s
    IdleTimeout SERVER_IDLE_TIMEOUT 120s

    WithMiddleware(mw ...func(http.Handler) http.Handler) Option

    Accumulates middleware applied to the root router during OnInit. Order is
    preserved and caller-controlled.

    Logger interface

    Duck-typed: requires only Info(msg string, args ...any) and
    Error(msg string, err error, args ...any). logz.Logger satisfies this directly.

    Lifecycle

    • OnInit — applies registered middleware to the router
    • OnStart — starts http.ListenAndServe in a background goroutine
    • OnStop — calls http.Server.Shutdown with a 10-second context timeout; in-flight requests have up to 10 seconds to complete

    Installation

    go get code.nochebuena.dev/go/httpserver@v0.9.0
    

    Requires code.nochebuena.dev/go/launcher and github.com/go-chi/chi/v5.

    Design Highlights

    chi over other frameworks. chi uses stdlib http.Handler everywhere. Every
    middleware in the micro-lib stack (httpmw) and every handler adapter (httputil)
    uses http.Handler/http.ResponseWriter/*http.Request natively. No wrapper
    code is required at any boundary.

    Embedded chi.Router. HttpServerComponent embeds chi.Router directly in the
    interface. Callers get the full routing API without delegation or wrapper methods.
    Route registration and lifecycle management happen on the same value.

    No default middleware. New() installs nothing. The middleware stack is composed
    explicitly with WithMiddleware(...) at construction time, keeping the stack visible
    and ordering unambiguous in the application source.

    Duck-typed Logger. The two-method Logger interface avoids a hard dependency on
    logz. Any struct with Info and Error methods satisfies it, including test stubs
    and application-local adapters.

    Known Limitations & Edge Cases

    • No TLS/HTTPS support. The server binds with http.ListenAndServe only. TLS
      termination is expected at the infrastructure layer (reverse proxy, load balancer).
    • The graceful shutdown drain timeout (10 seconds) is hardcoded in OnStop and is
      not configurable via Config or Option. Long-running streaming requests may be
      cut short if they exceed this window.
    • Middleware registered via srv.Use(mw) after OnInit has run may not behave as
      expected depending on chi's internal router state. All middleware should be
      provided via WithMiddleware at construction time.

    v0.9.0 → v1.0.0 Roadmap

    • Make the graceful shutdown timeout configurable (e.g., WithShutdownTimeout)
    • Evaluate optional TLS support via a WithTLS(certFile, keyFile string) Option
    • Production hardening: validate behavior under high concurrency and slow-client scenarios
    • Consider exposing a ServeHTTP method to enable embedding the server in test suites without binding a real port
    Downloads
  • v0.9.0 1ec0780f72

    Rene Nochebuena released this 2026-03-19 07:40:35 -06:00 | 4 commits to main since this release

    v0.9.0

    code.nochebuena.dev/go/httpserver

    Overview

    httpserver provides a lifecycle-managed HTTP server built on chi v5. It implements
    launcher.Component (OnInit → OnStart → OnStop) and embeds chi.Router directly,
    so a single value serves both as a lifecycle component and as the router for all route
    registration.

    This release reflects an API designed through multiple architecture reviews and
    validated end-to-end via the todo-api POC. It is versioned at v0.9.0 rather than
    v1.0.0 because it has not yet been exercised in production workloads across all edge
    cases, preserving the option for minor API refinements before committing to full
    stability.

    What's Included

    New(logger Logger, cfg Config, opts ...Option) HttpServerComponent

    Constructs the server component. No middleware is installed by default; the full
    middleware stack is composed explicitly at construction time via WithMiddleware.

    HttpServerComponent interface

    Embeds both launcher.Component and chi.Router, giving callers the complete chi
    routing API (Get, Post, Route, Mount, Use, With, Group, etc.) on the
    same value that participates in the launcher lifecycle.

    Config struct

    Field Env var Default
    Host SERVER_HOST 0.0.0.0
    Port SERVER_PORT 8080
    ReadTimeout SERVER_READ_TIMEOUT 5s
    WriteTimeout SERVER_WRITE_TIMEOUT 10s
    IdleTimeout SERVER_IDLE_TIMEOUT 120s

    WithMiddleware(mw ...func(http.Handler) http.Handler) Option

    Accumulates middleware applied to the root router during OnInit. Order is
    preserved and caller-controlled.

    Logger interface

    Duck-typed: requires only Info(msg string, args ...any) and
    Error(msg string, err error, args ...any). logz.Logger satisfies this directly.

    Lifecycle

    • OnInit — applies registered middleware to the router
    • OnStart — starts http.ListenAndServe in a background goroutine
    • OnStop — calls http.Server.Shutdown with a 10-second context timeout; in-flight requests have up to 10 seconds to complete

    Installation

    go get code.nochebuena.dev/go/httpserver@v0.9.0
    

    Requires code.nochebuena.dev/go/launcher and github.com/go-chi/chi/v5.

    Design Highlights

    chi over other frameworks. chi uses stdlib http.Handler everywhere. Every
    middleware in the micro-lib stack (httpmw) and every handler adapter (httputil)
    uses http.Handler/http.ResponseWriter/*http.Request natively. No wrapper
    code is required at any boundary.

    Embedded chi.Router. HttpServerComponent embeds chi.Router directly in the
    interface. Callers get the full routing API without delegation or wrapper methods.
    Route registration and lifecycle management happen on the same value.

    No default middleware. New() installs nothing. The middleware stack is composed
    explicitly with WithMiddleware(...) at construction time, keeping the stack visible
    and ordering unambiguous in the application source.

    Duck-typed Logger. The two-method Logger interface avoids a hard dependency on
    logz. Any struct with Info and Error methods satisfies it, including test stubs
    and application-local adapters.

    Known Limitations & Edge Cases

    • No TLS/HTTPS support. The server binds with http.ListenAndServe only. TLS
      termination is expected at the infrastructure layer (reverse proxy, load balancer).
    • The graceful shutdown drain timeout (10 seconds) is hardcoded in OnStop and is
      not configurable via Config or Option. Long-running streaming requests may be
      cut short if they exceed this window.
    • Middleware registered via srv.Use(mw) after OnInit has run may not behave as
      expected depending on chi's internal router state. All middleware should be
      provided via WithMiddleware at construction time.

    v0.9.0 → v1.0.0 Roadmap

    • Make the graceful shutdown timeout configurable (e.g., WithShutdownTimeout)
    • Evaluate optional TLS support via a WithTLS(certFile, keyFile string) Option
    • Production hardening: validate behavior under high concurrency and slow-client scenarios
    • Consider exposing a ServeHTTP method to enable embedding the server in test suites without binding a real port
    Downloads