Docs HTTP Server

HTTP Server

Plumego is not an HTTP server.

It does not replace Go’s net/http package,
and it does not abstract away the server lifecycle.

Instead, Plumego positions itself very deliberately:

Plumego is an HTTP handler framework, not a server runtime.

This distinction explains many of its design choices.


Plumego as an http.Handler

At its core, a Plumego application implements Go’s standard interface:

type Handler interface {
	ServeHTTP(http.ResponseWriter, *http.Request)
}

This means:

  • Plumego can be mounted on any net/http.Server
  • Plumego works with standard Go tooling
  • No custom server runtime is required
  • No behavior is hidden from the Go standard library

From Go’s perspective, Plumego is just another handler.


What Plumego Handles

Within the HTTP request lifecycle, Plumego is responsible for:

  • Creating the request-scoped Context
  • Executing the middleware chain
  • Routing the request
  • Invoking the matched handler
  • Writing the response (via handlers)

This entire flow happens inside ServeHTTP.

Plumego owns request execution, not process lifecycle.


What Plumego Does Not Handle

Plumego intentionally does not manage:

  • Server startup
  • Server shutdown
  • TLS configuration
  • Listener management
  • Port binding
  • Signal handling
  • Graceful shutdown orchestration

These are process-level concerns.

Delegating them to the framework would hide important behavior and reduce control.


Why Server Lifecycle Is Out of Core

Managing the HTTP server lifecycle involves tradeoffs that depend on:

  • Deployment environment
  • Container orchestration
  • Load balancers
  • Reverse proxies
  • Security requirements

There is no single “correct” choice.

Plumego therefore follows a strict rule:

Anything that varies by deployment environment must not live in the core.


Typical Plumego Server Setup

A minimal, explicit server setup looks like this:

app := plumego.New()

// register middleware and routes

server := &http.Server{
	Addr:    ":8080",
	Handler: app,
}

if err := server.ListenAndServe(); err != nil {
	log.Fatal(err)
}

Nothing is hidden.

Everything is visible and under your control.


Graceful Shutdown Is Explicit

Because Plumego does not manage the server lifecycle,
graceful shutdown must be implemented explicitly.

This is a feature, not a burden.

It ensures that:

  • Shutdown behavior is predictable
  • Timeouts are intentional
  • Resource cleanup is explicit
  • Production behavior matches expectations

(See Guides / Graceful Shutdown for details.)


HTTP Server Configuration Responsibility

All server-level configuration belongs outside Plumego:

  • Read/write timeouts
  • Header limits
  • Idle connection behavior
  • TLS settings

Example:

server := &http.Server{
	Addr:         cfg.HTTP.Addr,
	Handler:      app,
	ReadTimeout:  cfg.HTTP.ReadTimeout,
	WriteTimeout: cfg.HTTP.WriteTimeout,
}

Plumego does not guess defaults on your behalf.


Composability with net/http

Because Plumego is just an http.Handler, you can:

  • Mount it under a larger mux
  • Combine it with other handlers
  • Wrap it with standard net/http middleware
  • Serve multiple Plumego apps in one process

Example:

mux := http.NewServeMux()
mux.Handle("/api/", app)
mux.Handle("/metrics", metricsHandler)

Plumego does not require exclusivity.


HTTP Semantics Are Preserved

Plumego does not alter:

  • HTTP method semantics
  • Status code behavior
  • Header handling rules
  • Request/response streaming rules

If something works in net/http,
it works the same way with Plumego.

This reduces surprises and leverages Go’s stability.


Testing with the HTTP Server

Because Plumego integrates directly with net/http:

  • You can use httptest
  • You can test handlers end-to-end
  • No custom test harness is required

Example:

req := httptest.NewRequest("GET", "/health", nil)
rec := httptest.NewRecorder()

app.ServeHTTP(rec, req)

This keeps tests idiomatic and simple.


Common Misconceptions

“Plumego should manage shutdown for me”

Shutdown behavior is application policy, not framework behavior.


“Plumego should auto-start the server”

Auto-start hides configuration and reduces control.


“Plumego should wrap net/http completely”

That would reduce compatibility and transparency.


Why This Design Scales Better

By keeping HTTP server concerns outside the core:

  • Plumego remains stable over time
  • Integration remains flexible
  • Upgrades are low-risk
  • Production behavior stays explicit

Frameworks that absorb server lifecycle eventually become rigid.

Plumego deliberately avoids that path.


Summary

In Plumego:

  • The HTTP server is external
  • Plumego is an http.Handler
  • Request execution is owned by the framework
  • Process lifecycle is owned by the application
  • No server behavior is hidden

This separation is fundamental to Plumego’s philosophy.


Core Layer: Fully Complete

With Context, Router, Middleware, and HTTP Server covered,
you now understand every guarantee Plumego’s core makes — and every guarantee it refuses to make.

Nothing else is implicit.

Everything else is built on top, by design.