Files
headlamp-rook-plugin/docs/architecture/adr/002-extract-json-data.md
T
DevContainer User 61598f5f8b docs: add architecture decision records
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 13:49:57 +00:00

1.9 KiB

ADR 002: extractJsonData() Pattern for KubeObject Unwrapping

Status: Accepted

Date: 2026-03-05

Deciders: Development Team


Context

Headlamp's useList() hooks return arrays of KubeObject class instances that wrap raw JSON under .jsonData. The plugin's type system defines plain TypeScript interfaces (e.g., CephCluster, StorageClass) matching the raw Kubernetes JSON structure.

To use these typed interfaces, the KubeObject wrapper must be unwrapped. This pattern appears in every plugin that uses useList() hooks.


Decision

Implement an extractJsonData() utility function that takes a KubeObject instance and returns the unwrapped .jsonData property.

  • Apply this consistently to all useList() results before storing in context state.
  • All type guards (e.g., isRookCephProvisioner(), isRookCephStorageClass()) operate on the unwrapped plain objects, not on KubeObject wrappers.

Consequences

  • Clean separation between Headlamp's class instances and the plugin's typed interfaces
  • Type guards work on plain objects, which are easier to test
  • Consistent unwrapping pattern across all resources
  • ⚠️ Extra mapping step on every useList() result
  • ⚠️ Runtime cost of mapping arrays (negligible for typical cluster sizes of tens to hundreds of resources)

Alternatives Considered

  1. Use KubeObject instances directly — Rejected. Type guards and filters become harder to write and test with class wrappers.

  2. Type assertion (as CephCluster) — Rejected. Unsafe with no runtime validation; silently masks shape mismatches.

  3. Custom hook wrapping useList() with auto-extraction — Considered but extractJsonData() is simpler and more explicit. A wrapper hook would hide the unwrapping step, making the data flow less obvious.


Changelog

  • 2026-03-05: Initial decision accepted