Servekit owns HTTP bootstrap and presentation. Opskit owns the shared operations registry. Applications compose the two by registering operational components with Opskit and giving that one registry to Servekit.
This is the primary composition path for a service built from multiple Kit Series packages:
ops := opskit.NewRegistry()
// The application composition root registers components here. Components may
// come from sibling kits or from application code; Servekit does not need to
// know which package produced them.
ops.MustRegister(database, opskit.Required())
ops.MustRegister(buildInfo, opskit.Informational())
server := servekit.New(
servekit.WithOps(
ops,
servekit.WithOpsAdmin(),
servekit.WithOpsAdminAuthGate(requireAdmin),
),
)The resulting ownership stays narrow:
| Concern | Owner |
|---|---|
| HTTP listener, routing, encoding, and shutdown | Servekit |
| HTTP lifecycle readiness gate | Servekit |
| Shared component registration and readiness aggregation | Opskit |
| Component status, readiness, and inspection data | The registered component |
| Check scheduling and execution | Workerkit or application runtime |
| Command authorization and dispatch | Application control plane |
Servekit receives only *opskit.Registry. It does not import Configkit,
Workerkit, Dependkit, Clientkit, or any other domain kit. A sibling kit joins
the HTTP operations surface by implementing Opskit contracts and being
registered by the application.
examples/kit-series-composition is the
canonical single-service composition for the currently available kits. Its
application composition root:
- loads a typed Configkit manager
- registers a Dependkit registry as the required cached dependency signal
- gives that registry explicitly to a Workerkit check-group loop through Dependkit's released Opskit adapter
- registers the Configkit manager, Dependkit registry, and Workerkit runtime in one Opskit registry
- gives only that Opskit registry to Servekit
- starts and shuts down Workerkit explicitly around the Servekit server
The example does not mount Workerkit-specific command dispatch or lifecycle
routes. Generic /readyz and /admin/components requests remain passive;
focused Workerkit examples cover active HTTP controls separately.
The sibling modules appear in Servekit's go.mod because Go has no separate
development-dependency section and the repository builds its examples in CI.
They are not imported by Servekit's root package or linked into applications
that import only Servekit.
WithOps(ops) adds Opskit readiness to Servekit's built-in GET /readyz
decision. Readiness is evaluated in this order:
- Servekit lifecycle readiness.
- Opskit registry readiness.
- Lightweight predicates supplied with
WithReadinessChecks(...).
The lifecycle gate remains first so startup, explicit readiness, drain delay, and shutdown remain under Servekit's control.
The readiness response exposes only the aggregate decision and a stable generic
reason. It does not serialize Opskit component identities, states, reasons, or
messages, or errors returned by WithReadinessChecks(...). Custom readiness
check errors are logged at debug level for internal diagnosis.
Adding WithOpsAdmin() exposes two generic, read-only component routes:
GET /admin/componentsreturns registry inventory fromRegistry.Entries(). It does not evaluate component state.GET /admin/components/{name}returns a component snapshot fromRegistry.Snapshot(...), including its passive status, readiness, and safe inspection data when supported.
Servekit does not run checks or dispatch commands through these routes. Active operations belong in an execution layer that explicitly owns scheduling, authorization, concurrency, retries, and other runtime policy.
Opskit component status, readiness, and inspection methods should return local or cached state. A Kubernetes or load-balancer readiness probe must not fan out into fresh network checks on every request.
Run expensive dependency checks in the background, cache their latest result
in the component that owns that state, and let Opskit aggregate the cached
readiness view. WithOpsTimeout(...) supplies a context deadline to Opskit
readiness and snapshot evaluation, but component implementations must still
observe context cancellation.
WithReadinessChecks(...) remains useful for a small standalone service that
does not need an Opskit registry. Treat those functions as fast readiness
predicates over local state, not as an active dependency-check scheduler.
Admin routes are disabled unless WithOpsAdmin() is supplied. Once enabled,
they are unauthenticated unless the service adds
WithOpsAdminAuthGate(...) or equivalent network-level protection.
Component identity, readiness details, status attributes, and inspection data may be serialized by the opt-in admin routes. Components must therefore return only information safe for the protected operational audience. Do not include credentials, tokens, connection strings, user data, or other secrets.
See examples/operations for the small Servekit and
Opskit path. Continue with
examples/kit-series-composition for the
canonical current-kit service shell.