3.8 KiB
Runtime Composition
This document describes how the weatherapi executable wires configuration,
database handles, application services, HTTP endpoints, renderers, and shutdown.
It is development-facing; operator commands belong in
docs/operations.md, and configuration fields belong in
docs/config.md.
Purpose
cmd/weatherapi/main.go is the composition root. It should stay thin and only
connect already-implemented packages. Endpoint logic, SQL, presentation logic,
and business read behavior belong outside cmd.
Inputs and Outputs
Inputs:
- config path from
-config,WEATHERAPI_CONFIG, orconfig.yml; - feedapi YAML config containing
server,databases, andtemplates; - OS cancellation signals;
- database handles opened by feedapi.
Outputs:
- a configured feedapi HTTP server;
- registered
weatherapiendpoint definitions; - process logs for fatal startup errors and database close errors.
Composition Flow
The executable:
- sets standard logger flags with microsecond precision;
- resolves the config path;
- creates a context canceled by
os.InterruptorSIGTERM; - loads config with
feedapi/config.Load; - requires at least one configured database;
- opens all configured databases with
feedapi/db.OpenAll; - selects the first configured database name as the primary store;
- constructs
postgres.Repositorywith the primary*sql.DB; - constructs
app.Serviceover the repository; - builds HTTP endpoint definitions with
httpapi.Definitions; - constructs a feedapi app with the DB registry and endpoints;
- starts feedapi with the signal-aware context.
Config Fields Used
Runtime composition uses:
server: consumed by feedapi for HTTP runtime settings and default format;databases: opened by feedapi, with the first entry selected as primary;templates: consumed by feedapi for text-template loading.
Do not duplicate the config field reference here. Keep it in
docs/config.md.
External Adapters Used
feedapi/config: YAML loading.feedapi/db: database registry and lifecycle.feedapi/app: HTTP runtime construction and startup.internal/adapters/outbound/postgres: weather read repository.internal/adapters/inbound/httpapi: endpoint definition registry.github.com/lib/pq: Postgres driver registration through blank import.
State and Lifecycle
weatherapi owns no durable weather state. Runtime state is limited to loaded
configuration, database pools, endpoint definitions, renderer/template
registries managed by feedapi, and the running HTTP server.
Database handles are closed with a deferred registry close. Close errors are logged but do not change response behavior because they occur during shutdown.
Failure Behavior
run wraps startup errors with operation context:
load configconfig.databases requires at least one entryopen databasesselect primary databasebuild app
Errors returned by a.Start(ctx) are returned to main, which logs a fatal
weatherapi failed: ... message. Feedapi owns graceful HTTP shutdown after the
context is canceled.
Tests to Inspect Before Changing
internal/app/service_test.gofor service wiring expectations.internal/adapters/inbound/httpapi/endpoints_test.gofor endpoint registry and runtime adapter expectations.- Full
go test ./...when runtime wiring, config behavior, or feedapi integration changes.
Invariants
- Keep
cmd/weatherapias composition code only. - Preserve config path precedence:
-config,WEATHERAPI_CONFIG,config.yml. - Preserve first configured database as the primary weather store.
- Keep generic HTTP runtime behavior in feedapi.
- Keep endpoint definitions in the HTTP adapter.
- Keep SQL and row mapping in the Postgres adapter.