Plumego is a small Go HTTP toolkit built on the standard library, keeping
net/http compatibility at its center: handlers are ordinary
func(http.ResponseWriter, *http.Request), middleware wraps http.Handler,
and application wiring stays explicit in your own main package.
The stable surface is intentionally narrow. Start with core, router,
contract, and middleware; add security, store, health, log, and
metrics only when those responsibilities are needed.
main.go:
package main
import (
"log"
"net/http"
"github.com/spcent/plumego"
"github.com/spcent/plumego/contract"
)
func main() {
app := plumego.New()
app.Get("/ping", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_ = contract.WriteResponse(w, r, http.StatusOK, map[string]string{"message": "pong"}, nil)
}))
log.Fatal(http.ListenAndServe(":8080", app))
}Run:
go mod init example.com/hello
go get github.com/spcent/plumego@latest
go run main.goOpen http://localhost:8080/ping. For a production-style layout, read
reference/standard-service next.
For non-default address, timeouts, or TLS:
cfg := plumego.DefaultConfig()
cfg.Addr = ":9090"
app := plumego.NewWithConfig(cfg)For production wiring with explicit logger injection, use core.New directly —
see docs/start/getting-started.md.
| I want to build... | Start here |
|---|---|
| A plain JSON API | reference/standard-service → stable roots only |
| REST resources with CRUD conventions | reference/with-rest → x/rest |
| A multi-tenant SaaS API | reference/with-tenant → x/tenant |
| An API gateway or reverse proxy | reference/with-gateway → x/gateway |
| Real-time WebSocket features | reference/with-websocket → x/websocket |
| An AI-backed service | reference/with-ai → x/ai/provider |
| A service with rich messaging/webhooks | reference/with-messaging → x/messaging |
| A gRPC + HTTP service | reference/with-rpc → x/rpc |
| Observability (Prometheus / OpenTelemetry) | reference/with-observability → x/observability |
| A tenant administration console | reference/with-tenant-admin → x/tenant |
All paths keep reference/standard-service as the base layout; extensions are
explicit additions, not alternate bootstraps.
For Go services that need more structure than raw http.ServeMux without
taking on a large framework model.
| Principle | How plumego applies it |
|---|---|
| Standard library first | Ordinary handlers, middleware, requests, response writers, and *http.Server. |
| Explicit wiring | Routes, middleware, dependencies, and lifecycle are visible at construction sites. |
| Small stable surface | Stable roots have narrow ownership, not feature catalogs. |
| Agent-friendly maintenance | specs/, tasks/, and per-module module.yaml make scope and validation discoverable. |
| Optional capabilities | Product features and protocol adapters live outside the stable learning path. |
| Feature | http.ServeMux |
plumego |
|---|---|---|
| Basic routing | Method handling is caller-owned. | Get/Post/AddRoute register one method, path, handler. |
{param} extraction |
Caller parses path segments manually. | Router matches params; read from request context. |
| Route groups | Caller repeats prefixes manually. | Groups apply a shared prefix. |
| Per-group middleware | Caller composes handlers per subtree. | Groups carry shared middleware, keeping http.Handler shape. |
| Named routes + reverse URL | Caller builds URLs manually. | Reverse URL generation via the app/router API. |
| Route freeze | Routes mutable whenever wiring changes. | Prepare freezes routes before serving. |
| Structured errors | Caller defines every response shape. | contract.WriteError is the canonical error path. |
| Request ID carriage | Caller picks and propagates a convention. | Explicit context accessors + middleware support. |
| Graceful lifecycle | Caller builds setup and shutdown policy. | Prepare, Server, Shutdown keep it explicit and reusable. |
| Package | Role |
|---|---|
core |
App construction, route registration, middleware attachment, server lifecycle. |
router |
Route matching, path params, groups, metadata, reverse URL generation. |
contract |
Response writers, structured error builders, request metadata, transport binding. |
middleware |
Transport-only middleware composition and first-party packages. |
security |
Auth, JWT, password, security headers, input-safety, abuse guards. |
store |
Stable storage contracts and in-memory primitives (cache, KV, file, DB, idempotency). |
health |
Health/readiness models for app and dependency status. |
log |
Minimal logging interfaces and a default logger. |
metrics |
Minimal metrics contracts (counters, gauges, timings, collectors). |
Optional capability families live under x/* — additions to the stable root
path, not alternate layouts.
Plumego is maintained with an agent-first control plane: docs/ explains the
architecture, specs/ records machine-checkable boundaries, tasks/ defines
reviewable execution units, and reference/ shows canonical wiring. Checks
under internal/checks/ enforce key boundaries locally and in CI, so automated
changes produce reviewable evidence instead of implicit convention. See
docs/concepts/agent-first.md for the model
and adoption path, and
docs/operations/agent-first-operating-reference.md
for the internal operating reference.
docs/start/getting-started.md— smallest runnable walkthrough.reference/standard-service— canonical app layout.docs/reference/canonical-style-guide.md— handler, middleware, routing, DI conventions.docs/modules— package-specific primers.docs/start/adoption-path.md— 5-minute, 30-minute, 1-day adoption path.docs/start/troubleshooting.md— route freeze, middleware order, JWT errors, lifecycle issues.docs/evidence/benchmarks/README.md— performance vs Chi, Gin, Echo.