api

command
v0.0.0-...-b3a3c75 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 30, 2026 License: MIT Imports: 21 Imported by: 0

README

cmd/api

Purpose

cmd/api is the entry point for the eshu-api binary. It boots OTEL telemetry, opens a Postgres connection and an optional graph driver, wires all query handlers through internal/query, mounts the shared runtime admin surface, wraps the combined mux with bearer-token authentication, and listens for HTTP traffic until SIGINT or SIGTERM.

Where this fits in the pipeline

flowchart LR
  Client["HTTP / CLI client"] --> API["cmd/api\n(eshu-api)"]
  API --> QH["internal/query\nAPIRouter.Mount"]
  QH --> GQ["GraphQuery port\n(Neo4jReader)"]
  QH --> CS["ContentStore port\n(ContentReader)"]
  GQ --> Graph["Graph backend\n(Neo4j / NornicDB)"]
  CS --> PG["Postgres\ncontent store"]
  API --> Admin["internal/runtime\nNewStatusAdminMux"]

Internal flow

flowchart TB
  A["main()"] --> B["telemetry.NewBootstrap\ntelemetry.NewProviders"]
  B --> C["wireAPI(ctx, os.Getenv, ...)"]
  C --> D["loadQueryProfile\nloadGraphBackend"]
  D --> E["openQueryGraph\n(optional Neo4j/NornicDB driver)"]
  E --> F["sql.Open + PingContext\n(Postgres)"]
  F --> G["query.NewNeo4jReader\nquery.NewContentReader"]
  G --> H["newRouter\n(builds query.APIRouter)"]
  H --> I["apiMux := http.NewServeMux\nrouter.Mount(apiMux)"]
  I --> J["mountRuntimeSurface\ninternalruntime.NewStatusAdminMux"]
  J --> K["query.AuthMiddleware wraps mux"]
  K --> L["http.Server on ESHU_API_ADDR\nwrapped in otelhttp"]
  L --> M["srv.ListenAndServe"]
  M -- SIGINT/SIGTERM --> N["srv.Shutdown (5s timeout)\ncleanup() closes Postgres + driver"]

Lifecycle / workflow

main initializes OTEL via telemetry.NewBootstrap and telemetry.NewProviders, then calls wireAPI. Failure at any wiring step releases already-acquired connections and exits; the cleanup closure returned by wireAPI closes Postgres and the graph driver on normal shutdown.

wireAPI resolves ESHU_QUERY_PROFILE and ESHU_GRAPH_BACKEND, opens the graph driver via openQueryGraph (skipped when ESHU_QUERY_PROFILE=local_lightweight), opens and pings Postgres, then calls newRouter to build the query.APIRouter with all handler structs wired to the concrete query.Neo4jReader and query.ContentReader adapters. The supply-chain handler also wires AdvisoryEvidence to query.NewPostgresAdvisoryEvidenceStore so source-only advisory evidence is available through the API without requiring graph access.

mountRuntimeSurface calls internalruntime.NewStatusAdminMux to compose /healthz, /readyz, /admin/status, and /metrics alongside the API routes. The combined mux is then wrapped with query.AuthMiddleware.

The HTTP server listens on ESHU_API_ADDR (default :8080) with a 10 s read-header timeout, 60 s write timeout, and 120 s idle timeout. On shutdown it waits up to 5 s for in-flight requests before exiting.

Exported surface

cmd/api is a package main binary; it exports no Go identifiers. All handler and contract types are owned by internal/query.

The direct process contract includes eshu-api --version and eshu-api -v. Both flags print the build-time version through printAPIVersionFlag, which wraps buildinfo.PrintVersionFlag, before telemetry, Postgres, or graph setup begins.

Two compile-time interface checks in wiring.go:23–24 assert that *query.Neo4jReader satisfies query.GraphQuery and *query.ContentReader satisfies query.ContentStore. These checks fail the build if either concrete type drifts from the port it implements.

See doc.go for the full godoc contract.

Dependencies

  • internal/queryAPIRouter, RepositoryHandler, EntityHandler, CodeHandler, ContentHandler, InfraHandler, IaCHandler, ImpactHandler, EvidenceHandler, SupplyChainHandler, StatusHandler, CompareHandler, AdminHandler, Neo4jReader, ContentReader, AuthMiddleware, ParseQueryProfile, ParseGraphBackend
  • internal/runtimeOpenNeo4jDriver, ResolveAPIKey, NewStatusAdminMux, NewStatusRequestHandler
  • internal/recoveryNewHandler for refinalize/replay routes
  • internal/statusReader port consumed by internalruntime.NewStatusAdminMux
  • internal/storage/postgresNewStatusStore, NewRecoveryStore, NewStatusRequestStore
  • internal/telemetryNewBootstrap, NewProviders, EventAttr, NewLoggerWithWriter

Configuration

  • ESHU_API_ADDR — listen address, default :8080
  • ESHU_POSTGRES_DSN (or legacy ESHU_CONTENT_STORE_DSN) — required
  • ESHU_QUERY_PROFILE — default production
  • ESHU_GRAPH_BACKENDneo4j or nornicdb
  • ESHU_DISABLE_NEO4J — with the local-lightweight profile, skips the graph driver
  • DEFAULT_DATABASE — graph database name, default nornic
  • ESHU_PPROF_ADDR — opt-in net/http/pprof endpoint via runtime.NewPprofServer; unset disables the profiler; port-only inputs (:6060) bind to 127.0.0.1
  • API key resolved via runtime.ResolveAPIKey; Bolt details via runtime.OpenNeo4jDriver

Telemetry

  • Bootstrap: telemetry.NewBootstrap("eshu-api") with service name api, logger component api.
  • HTTP middleware: otelhttp.NewHandler(mux, "eshu-api") instruments every request with OTEL spans and read/write message events.
  • Metrics: /metrics exposed via internalruntime.WithPrometheusHandler.
  • Log events (via telemetry.EventAttr): runtime.startup.failed, runtime.postgres.connected, runtime.neo4j.connected, runtime.server.listening, runtime.server.stopped, runtime.server.failed, runtime.shutdown.failed.

Operational notes

  • If /healthz returns unhealthy, check that both Postgres (PingContext) and the graph driver were reachable at startup; wiring failures cause os.Exit(1).
  • High request latency: check eshu_dp_neo4j_query_duration_seconds and eshu_dp_postgres_query_duration_seconds at /metrics before scaling the API. Query latency is owned by internal/query handlers, not the transport layer.
  • 5xx spikes: look at the otelhttp span error attributes and the structured log stream; per-handler errors surface as JSON error responses, not panics.
  • /admin/status reports the live runtime stage and backlog from internal/status. A healthy API with empty or stale admin/status data means the ingester or reducer has not yet populated status rows.
  • ESHU_DISABLE_NEO4J=true with ESHU_QUERY_PROFILE=local_lightweight skips graph driver initialization; the API then serves Postgres-only content queries.
  • Graceful shutdown waits at most 5 s; in-flight graph or content reads that exceed this window are interrupted. Check write-timeout settings if clients report disconnects under load.

Extension points

  • Graph backend: implement query.GraphQuery and wire the new adapter in openQueryGraph. The rest of the binary does not branch on backend brand.
  • Auth: replace query.AuthMiddleware with a different policy by swapping the middleware call in wireAPI. The token is resolved via internalruntime.ResolveAPIKey.
  • Admin surface: internalruntime.NewStatusAdminMux accepts internalruntime.WithPrometheusHandler and other options; add new admin routes through internal/runtime, not directly in this binary.

Gotchas / invariants

  • Reads only. This binary does not write facts, enqueue projection work, or touch the reducer queue. Writes belong to ingester, projector, or reducer.

  • Version probes are pre-startup checks. Keep printAPIVersionFlag at the top of main so eshu-api --version works without database credentials.

  • ESHU_POSTGRES_DSN is required; after ResolveAPIKey succeeds, startup fails with an explicit error if both ESHU_POSTGRES_DSN and the legacy ESHU_CONTENT_STORE_DSN are empty (wiring.go:42).

  • Invalid ESHU_QUERY_PROFILE or ESHU_GRAPH_BACKEND values fail at startup via ParseQueryProfile and ParseGraphBackend; there is no silent default for unrecognized values.

  • wireAPI returns a cleanup closure. PrometheusHandler and all acquired connections are freed when the closure runs; partial wiring failures still free already-acquired connections (main.go:67).

  • The API mux is wrapped with AuthMiddleware before it is handed to the HTTP server; do not add unprotected data routes after this wrap point.

  • docs/public/deployment/service-runtimes.md — API runtime lane and scaling notes
  • docs/public/reference/http-api.md — canonical HTTP API contract
  • docs/public/reference/cli-reference.mdeshu api start flags
  • docs/public/run-locally/docker-compose.md — Compose service eshu
  • docs/public/reference/backend-conformance.md — backend selection

Documentation

Overview

Package main runs the eshu-api binary, which serves the Eshu HTTP query and admin surface backed by the configured graph backend and Postgres content store.

When invoked with --version or -v, it prints the embedded application version through the test-covered printAPIVersionFlag helper and exits before runtime setup. Otherwise the binary boots OTEL telemetry, wires the query router and the shared runtime admin mux, including Postgres-backed supply chain attachment, advisory evidence, impact finding, and impact explanation reads, and listens on ESHU_API_ADDR (default :8080) wrapped in otelhttp instrumentation. On SIGINT or SIGTERM it gives the HTTP server up to five seconds for graceful shutdown before exiting. The runtime serves reads only; it does not own repo sync, parsing, fact emission, or queued projection work.

When ESHU_PPROF_ADDR is set, the binary also exposes an opt-in net/http/pprof endpoint via runtime.NewPprofServer, bound to 127.0.0.1 for port-only inputs so the default does not reach beyond the local host.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL