You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Kubernetes API supports HTTP requests that return alternative representations of resources via content negotiation using the Accept header. Two key response formats are currently not supported by the Fabric8 Kubernetes Client DSL:
Returns a meta.k8s.io/v1/Table object with column definitions and rows — the same format kubectl get uses for display. This is useful for tools that need to display resources in a tabular format without downloading the full resource payloads.
Returns resources with only the metadata field populated, omitting spec and status. This significantly reduces response sizes when only metadata (labels, annotations, owner references, etc.) is needed.
Both features use the same underlying mechanism (Accept header content negotiation) and can share the same infrastructure changes.
Use Cases
Memory reduction: A single Pod descriptor can be >50KB. When listing thousands of pods for status monitoring, PartialObjectMetadata drastically reduces memory consumption (Receiving resources as Tables #6823).
Tool/UI integration: Table format provides server-defined columns, useful for CLI tools, dashboards, and MCP servers (e.g., kubernetes-mcp-server already uses table format for list output).
Efficient informers: PartialObjectMetadata informers could watch large numbers of resources while storing minimal data (complementing the existing ReducedStateItemStore).
Current State and Challenges
The type-safety challenge
The DSL is strongly typed through generics <T, L, R>:
The list() return type is baked in as L (= PodList). There is no way to change the return type to Table or PartialObjectMetadataList mid-chain without breaking the generic contract.
No Accept header support
Currently, the HTTP requests built by OperationSupport.handleResponse() and BaseOperation.submitList() do not set any Accept header, defaulting to the server's standard JSON response.
Missing model classes
Table, TableColumnDefinition, TableRow, PartialObjectMetadata, and PartialObjectMetadataList do not exist as model classes in the project.
Proposed Approaches
Approach A: Type-switching method on the DSL chain
Add methods that change the return type of subsequent operations:
How it works: asPartialObjectMetadata() returns a new Listable<PartialObjectMetadataList> (NOT the full FilterWatchListDeletable). Similarly, asTable() returns Listable<Table>.
Pros: Clean fluent API, type-safe chain. Cons: Complex generic type changes. asPartialObjectMetadata() on FilterWatchListDeletable<Pod, PodList, Resource<Pod>> must return a different generic type, breaking the chain's type parameter flow. Requires new wrapper classes/interfaces to represent the "type-switched" state.
Approach B: Overloaded list() with response type parameter
publicinterfaceListable<T> {
Tlist();
<R> Rlist(Class<R> responseType); // new
}
Pros: Minimal interface changes, simple to implement. Cons: Less type-safe. The relationship between the class and the accept header is implicit. Doesn't naturally extend to get(). Users could pass arbitrary classes.
Approach C: New terminal methods on existing interfaces (Recommended)
Add new methods alongside existing list() and resources():
// New interfacepublicinterfaceMetadataListable {
TablelistAsTable();
TablelistAsTable(ListOptionsoptions);
PartialObjectMetadataListlistAsPartialObjectMetadata();
PartialObjectMetadataListlistAsPartialObjectMetadata(ListOptionsoptions);
}
publicclassPartialObjectMetadataimplementsHasMetadata {
privateStringapiVersion;
privateStringkind;
privateObjectMetametadata;
// No spec, no status - that's the point
}
publicclassPartialObjectMetadataListextendsDefaultKubernetesResourceList<PartialObjectMetadata> {
}
// For list operationspublicinterfaceMetadataListable {
TablelistAsTable();
TablelistAsTable(ListOptionsoptions);
PartialObjectMetadataListlistAsPartialObjectMetadata();
PartialObjectMetadataListlistAsPartialObjectMetadata(ListOptionsoptions);
}
// For single-resource get operationspublicinterfaceMetadataGettable {
PartialObjectMetadatagetAsPartialObjectMetadata();
}
2.2 Integration points
FilterWatchListDeletable extends MetadataListable — available after namespace/filter operations
Resource extends MetadataGettable — available for single-resource operations
Description
The Kubernetes API supports HTTP requests that return alternative representations of resources via content negotiation using the
Acceptheader. Two key response formats are currently not supported by the Fabric8 Kubernetes Client DSL:1. Table format (#6823)
Returns a
meta.k8s.io/v1/Tableobject with column definitions and rows — the same formatkubectl getuses for display. This is useful for tools that need to display resources in a tabular format without downloading the full resource payloads.2. PartialObjectMetadata (#5716)
Returns resources with only the
metadatafield populated, omittingspecandstatus. This significantly reduces response sizes when only metadata (labels, annotations, owner references, etc.) is needed.For list operations:
Both features use the same underlying mechanism (Accept header content negotiation) and can share the same infrastructure changes.
Use Cases
ReducedStateItemStore).Current State and Challenges
The type-safety challenge
The DSL is strongly typed through generics
<T, L, R>:The
list()return type is baked in asL(=PodList). There is no way to change the return type toTableorPartialObjectMetadataListmid-chain without breaking the generic contract.No Accept header support
Currently, the HTTP requests built by
OperationSupport.handleResponse()andBaseOperation.submitList()do not set anyAcceptheader, defaulting to the server's standard JSON response.Missing model classes
Table,TableColumnDefinition,TableRow,PartialObjectMetadata, andPartialObjectMetadataListdo not exist as model classes in the project.Proposed Approaches
Approach A: Type-switching method on the DSL chain
Add methods that change the return type of subsequent operations:
How it works:
asPartialObjectMetadata()returns a newListable<PartialObjectMetadataList>(NOT the fullFilterWatchListDeletable). Similarly,asTable()returnsListable<Table>.Pros: Clean fluent API, type-safe chain.
Cons: Complex generic type changes.
asPartialObjectMetadata()onFilterWatchListDeletable<Pod, PodList, Resource<Pod>>must return a different generic type, breaking the chain's type parameter flow. Requires new wrapper classes/interfaces to represent the "type-switched" state.Approach B: Overloaded list() with response type parameter
Add a new overload to
Listable:Pros: Minimal interface changes, simple to implement.
Cons: Less type-safe. The relationship between the class and the accept header is implicit. Doesn't naturally extend to
get(). Users could pass arbitrary classes.Approach C: New terminal methods on existing interfaces (Recommended)
Add new methods alongside existing
list()andresources():Mix into existing hierarchy:
Usage:
For single-resource get (on
Resource):Pros:
Table,PartialObjectMetadataList)resources()(Stream<R>) was added alongsidelist()(L) inFilterWatchListDeletableCons:
Detailed Implementation Plan (Approach C)
Phase 1: Infrastructure
1.1 Model classes
Add to
kubernetes-model-generator(orkubernetes-client-apias simple POJOs):Table (meta.k8s.io/v1):
PartialObjectMetadata (meta.k8s.io/v1):
1.2 Accept header constants
Phase 2: DSL Interfaces
2.1 New interfaces in
kubernetes-client-api2.2 Integration points
FilterWatchListDeletableextendsMetadataListable— available after namespace/filter operationsResourceextendsMetadataGettable— available for single-resource operationsPhase 3: Implementation in BaseOperation
3.1 New internal method
This mirrors the existing
submitList()(line 428) but:TypeReferenceinstead of using the hardcodedlistTypeReferenceAcceptheader on the request builder3.2 Public implementations
Phase 4 (Future): Informer support
The
ListerWatcher<T, L>interface currently ties list responses toL. PartialObjectMetadata informers would:ACCEPT_PARTIAL_METADATA_LIST_V1for the initial listACCEPT_PARTIAL_METADATA_V1for watch eventsReducedStateItemStorewhich already supports reduced-state informers on the storage sideThis could be exposed as:
Key Files Reference
kubernetes-client-api/.../dsl/Listable.javalist()returnsLkubernetes-client-api/.../dsl/Gettable.javaget()returnsTkubernetes-client-api/.../dsl/FilterWatchListDeletable.javaresources()kubernetes-client-api/.../dsl/Resource.javaFromServerGettable<T>kubernetes-client/.../internal/OperationContext.javakubernetes-client/.../internal/OperationSupport.javakubernetes-client/.../internal/BaseOperation.java:428-446submitList()— builds HTTP request, no Accept headerkubernetes-client/.../internal/BaseOperation.java:791-795handleGet()— single-resource GETkubernetes-client/.../internal/BaseOperation.java:1114-1116resources()— precedent for terminal methodskubernetes-client/.../informers/cache/ReducedStateItemStore.javaRelated Issues
Both issues are addressed by this proposal since they share the same underlying mechanism (Accept header content negotiation).