Skip to content

Getting Started

Open the reference service directly in a browser-based dev environment — no local Go install needed:

Open in GitHub Codespaces

Inside the Codespace the Go toolchain is pre-installed. Run:

Terminal window
cd reference/standard-service
go run .

Then open the forwarded port and verify:

Terminal window
curl http://localhost:8080/healthz
# {"data":{"status":"ok","service":"plumego-reference","timestamp":"2026-06-08T00:00:00Z"}}

Requirements: Go 1.26+ and an existing Go module (go.mod).

Terminal window
go mod init myservice # skip if you already have a module
go get github.com/spcent/plumego@latest

Create main.go:

package main
import (
"net/http"
"github.com/spcent/plumego/contract"
"github.com/spcent/plumego/core"
plog "github.com/spcent/plumego/log"
)
func main() {
app := core.New(core.DefaultConfig(),
core.AppDependencies{Logger: plog.NewLogger()})
_ = app.Get("/ping", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_ = contract.WriteResponse(w, r, http.StatusOK,
map[string]string{"status": "ok"}, nil)
}))
app.Run() // combined prepare + listen on :8080
}

Run and verify:

Terminal window
go run .
# 2026/06/06 00:00:00 server listening on :8080
curl http://localhost:8080/ping
# {"data":{"status":"ok"},"request_id":""}

The data wrapper and request_id field are part of the contract response envelope. Add middleware/requestid before app.Run() to populate the request ID on every response.

Two lifecycle patterns: app.Run() is the combined path — prepare, wire, and start in one call. If you need to inspect or wrap the *http.Server before it starts (custom TLS, connection tracking, or test embedding), use app.Prepare() + app.Server() instead. See the core module primer for the full API.

SignalProves
contract.WriteResponse wraps the mapSuccess responses use the stable transport contract
app.Get(path, http.HandlerFunc(...))Route registration is explicit — no hidden init()
app.Run() in one callLifecycle is explicit and composable — the server starts where you see it

Clone and run the reference app to see the complete directory layout — config loading, health endpoints, handler separation, and constructor-based dependency wiring.

Terminal window
git clone https://github.com/spcent/plumego
cd plumego/reference/standard-service
go run .

Verify:

Terminal window
curl http://localhost:8080/healthz
# {"data":{"status":"ok","service":"plumego-reference","timestamp":"2026-06-08T00:00:00Z"}}
curl 'http://localhost:8080/api/v1/greet?name=Alice'
# {"data":{"message":"hello, Alice"}}

Four files cover the entire shape:

FileWhat to inspect
reference/standard-service/main.goBootstrap order
reference/standard-service/internal/app/app.goExplicit dependency wiring
reference/standard-service/internal/app/routes.goRoute ownership in one place
reference/standard-service/internal/handler/api.goHandler shape: stdlib-compatible

After the smallest example works, keep the app layout from reference/standard-service and add only the capability family you need:

GoalFirst module
Standard JSON API with explicit handlersstable roots: core, router, contract, middleware
Reusable CRUD and resource conventionsx/rest
Tenant resolution, policy, quota, and isolationx/tenant
Reverse proxy, rewrite, balancing, and edge transportx/gateway, then x/gateway/discovery only when dynamic backend lookup is required
WebSocket transportx/websocket
Messaging workflowsx/messaging
Inbound webhook verification or outbound webhook deliveryx/messaging/webhook, starting from x/messaging when the task is broader than transport mechanics
File upload, download, and temporary URL transportx/fileapi, with storage and metadata implementations in x/data/file
Reusable circuit breaker or rate-limit primitivesx/resilience
AI providers, sessions, streaming, and toolsx/ai/provider, x/ai/session, x/ai/streaming, x/ai/tool
Observability export, protected diagnostics, or local debug endpointsx/observability, x/observability/ops, or x/observability/devtools depending on the surface
gRPC + HTTP service hosting or outbound RPC client poolingx/rpc
OpenAPI 3.1 document generation from registered routesx/openapi
Explicit JSON binding and caller-owned request validationx/validate

Do not start a new application layout from an x/* package. Extensions are explicit additions to the canonical app wiring in reference/standard-service.


Next questionGo to
Which files should I copy from?Reference App
How does the request path work?Request Flow
Which stable root or x/* family should I open?Modules Overview
Can I depend on this package long term?Release Posture
Common questions (auth, database, comparison with Gin)FAQ