ADR-0001: Hosts Top-Level Response Shape for GET /v1/ingresses

Status

Proposed | Accepted | Rejected | Superseded | Deprecated

Codes Legend

  • CTR-###: Context item
  • DEC-###: Decision statement
  • POS-###: Positive consequence
  • NEG-###: Negative consequence
  • ALT-###: Alternative considered
  • IMP-###: Implementation note
  • CHG-###: Change propagation step
  • REF-###: Reference entry

Context

CTR-001: Prior drafts of the specification described GET /v1/ingresses as a nested structure with an outer array of ingress records (each with namespace/name) and nested hosts[] with paths[].

CTR-002: The primary client for this service is a user-facing link portal that needs to render links to web services (hosts and paths) deployed in the cluster. For this use case, the ingress namespace/name grouping is not required in the response payload.

CTR-003: The project has not been deployed yet, so we can make a breaking response shape change without introducing a new API version (COMP-001 allows breaking changes pre-release; post-release would require /v2).

CTR-004: ETag semantics are based on underlying resourceVersions; re-shaping the response does not inherently change the ETag computation policy (AC-003 unaffected). Naming conventions (camelCase vs snake_case) are out of scope for this ADR and may be considered separately.

Decision

DEC-001: Change the response shape of API-001 (GET /v1/ingresses) to promote hosts to the top level and remove the outer array of ingress records and their namespace/name fields.

DEC-002: New response contract:

  • Top-level object with a single key: hosts
  • hosts: array of HostEntry objects (as already defined in the spec), each including its paths[] of PathEntry objects
  • The fields present within HostEntry and PathEntry remain unchanged by this ADR (no renaming); only the structural shape changes
  • Deterministic sorting is applied by (host, path) at render time, replacing the prior (namespace, name, host, path) order

Illustrative example (non-normative):

{ “hosts”: [ { “host”: “shop.example.com”, “servicename”: “shop-frontend”, “user_group”: “web”, “description”: “Customer storefront”, “contact_information”: “oncall@example.com”, “missing_annotations”: false, “paths”: [ { “path”: “/”, “pathType”: “Prefix”, “backendService”: “shop-frontend”, “reachability”: “reachable” } ] } ] }

Consequences

Positive

  • POS-001: Payload focuses on portal needs (hosts and paths), reducing clients’ parsing complexity.
  • POS-002: Smaller response size by removing redundant ingress grouping fields.
  • POS-003: Simpler deterministic ordering based on externally visible attributes (host, path).

Negative

  • NEG-001: Loses explicit linkage to source Ingress (namespace/name) in the response; operators may need logs or additional tooling for reverse lookup.
  • NEG-002: Breaks the previously described schema; any prototype clients must be updated in lockstep.
  • NEG-003: If multiple ingresses contribute to the same host, provenance is not visible in the response without extra instrumentation.

Alternatives Considered

Keep Nested Structure (ingress[] → hosts → paths)

  • ALT-001: Description: Retain existing grouping by ingress namespace/name with hosts nested under each ingress.
  • ALT-002: Rejection Reason: Adds complexity for the primary portal client and increases payload size; grouping is not directly needed for link rendering.

Flat Routes Array

  • ALT-003: Description: Return a top-level routes[] where each element flattens (host, path, backend) and duplicates host-level metadata.
  • ALT-004: Rejection Reason: Overly denormalizes data and can bloat payloads when hosts have many paths; host-level metadata would be repeated.

Versioned Change (/v2)

  • ALT-005: Description: Introduce /v2/ingresses with the new shape, keep /v1 as-is.
  • ALT-006: Rejection Reason: Not yet deployed; versioning now adds unnecessary complexity. Per COMP-001, we can make the change pre-release.

Implementation Notes

  • IMP-001: Update docs/specification.md:
    • Replace the JSON Schema (8.2) to define a top-level object with property hosts (array of HostEntry) and remove the nested ingress records array.
    • Update API-001 response example to the new shape; remove namespace/name from examples.
    • Update FR-008/AC-002 to specify deterministic sort by (host, path).
  • IMP-002: Server implementation:
    • Adjust projection-to-API mapping to emit hosts[] directly; remove the outer array of ingress records.
    • Ensure sorting by (host, path) before serialization to stabilize ETag exposure.
    • Keep ETag policy unchanged (derived from underlying resourceVersions map).
  • IMP-003: Tests and Observability:
    • Update unit tests for sorting, schema validation, and handler response.
    • Update OpenAPI generation to reflect the new schema; verify AC-008.
    • Confirm metrics and health endpoints remain unaffected.

Change Propagation Checklist

Upon status: Accepted, execute and track the following updates:

  • CHG-001: Update docs/specification.md (API-001 schema and examples; FR-008/AC-002 sort order; remove nested ingress records definitions).
  • CHG-002: Update any high-level plan(s) under docs/plan/ once created (TASKs and traceability).
  • CHG-003: Update Feature Breakdown(s) (once authored) to align WI definitions and tests with the new shape.
  • CHG-004: Update documentation (tutorials/how-to/reference/explanations) to show the new response example.
  • CHG-005: Communicate via PR referencing ADR-0001; include rationale and migration notes (no deployed users).
  • CHG-006: If later superseded, update this ADR’s status and set superseded_by.

References

  • REF-001: docs/specification.md (status Draft), Sections 8.2 (Data Schemas), 9 (API Specification), 17 (Acceptance Criteria), 14 (Compatibility and Versioning).

Next Steps

  • After this ADR is accepted, run .github/prompts/propagate-adr.prompt.md with ${input:ADRPath} pointing to docs/adr/adr-0001-hosts-top-level-response.md to update the spec, plans, breakdowns, and docs.

Model Guidance

  • Use a mid/high-tier reasoning model for tradeoffs and structured writing.
  • Suggested params: temperature 0.1–0.2.

Guardrails: Code Changes

  • This ADR does not modify source code.
  • Save and review this ADR; apply changes via the propagate ADR workflow and implement via work items.