Skip to content

Introduce Fully Qualified Container Type Metadata #27

Description

@bsayli

Is your feature request related to a problem?

Problem statement

OpenAPI Generics 1.1 introduced first-class generic container support through a shared container infrastructure.

Supported response contracts currently include:

ServiceResponse<T>
ServiceResponse<List<T>>
ServiceResponse<Set<T>>
ServiceResponse<Page<T>>

and equivalent BYOE contracts:

ApiResponse<T>
ApiResponse<List<T>>
ApiResponse<Set<T>>
ApiResponse<Page<T>>

Projection currently emits container metadata using logical container names:

x-data-container: List
x-data-container: Set
x-data-container: Page

This is sufficient for the currently supported built-in containers.

However, the projection metadata does not preserve the actual Java container type discovered during response introspection.

For example:

x-data-container: Page

only communicates the semantic container name.

The actual Java type identity is lost during projection even though it is already known by the introspection pipeline.

Likewise:

x-data-container: Set

does not explicitly preserve the fact that the container originated from:

java.util.Set

The platform already resolves container identity through:

SupportedContainerType

but that information is currently discarded when generating OpenAPI metadata.

As a result, projection metadata contains only semantic container information and not the actual Java container identity discovered during introspection.


Describe the solution you'd like

Preserve the fully qualified Java container type in OpenAPI vendor extensions.

Current metadata:

x-data-container: Page
x-data-item: CustomerDto

Proposed metadata:

x-data-container: Page
x-data-container-type: io.github.blueprintplatform.openapi.generics.contract.paging.Page
x-data-item: CustomerDto

Additional examples:

x-data-container: List
x-data-container-type: java.util.List
x-data-item: CustomerDto
x-data-container: Set
x-data-container-type: java.util.Set
x-data-item: CustomerDto

The existing semantic metadata remains unchanged.

The new metadata simply preserves information that is already available during introspection.


Proposed model

The existing container model already contains the information required to support this feature.

Example:

public record SupportedContainerType(
    Class<?> type,
    String schemaName,
    String containerName
) {

    public String containerTypeName() {
        return type.getName();
    }
}

The SupportedContainerType model owns Java-side container identity:

Java container type
Schema name
Semantic container name

Container schema shape remains an internal projection concern represented by the existing container schema strategies, resolvers, and item extractors.

Examples:

List<T>  -> Wrapper payload array schema + direct array item extraction
Set<T>   -> Wrapper payload array schema + direct array item extraction
Page<T>  -> Component container schema + content array item extraction

No container shape information is projected into OpenAPI metadata.

Only the fully qualified Java container type is exposed.

Vendor extensions become:

public static final String DATA_CONTAINER = "x-data-container";
public static final String DATA_CONTAINER_TYPE = "x-data-container-type";
public static final String DATA_ITEM = "x-data-item";

Example projection

Current:

ServiceResponsePageCustomerDto:
  x-api-wrapper: true
  x-api-wrapper-datatype: PageCustomerDto
  x-data-container: Page
  x-data-item: CustomerDto

Proposed:

ServiceResponsePageCustomerDto:
  x-api-wrapper: true
  x-api-wrapper-datatype: PageCustomerDto
  x-data-container: Page
  x-data-container-type: io.github.blueprintplatform.openapi.generics.contract.paging.Page
  x-data-item: CustomerDto

Collection example:

ServiceResponseSetCustomerDto:
  x-api-wrapper: true
  x-api-wrapper-datatype: SetCustomerDto
  x-data-container: Set
  x-data-container-type: java.util.Set
  x-data-item: CustomerDto

List example:

ServiceResponseListCustomerDto:
  x-api-wrapper: true
  x-api-wrapper-datatype: ListCustomerDto
  x-data-container: List
  x-data-container-type: java.util.List
  x-data-item: CustomerDto

Architectural outcome

Container metadata becomes more explicit and deterministic.

The projection pipeline remains unchanged:

Java Contract
        ↓
Response Introspection
        ↓
Container Metadata
        ↓
OpenAPI Projection
        ↓
Vendor Extensions
        ↓
Code Generation
        ↓
Wrapper Reconstruction

The difference is that container identity is now preserved rather than discarded during projection.

The Java container identity flows from introspection into projection metadata:

SupportedContainerType.type()
        ↓
SupportedContainerType.containerTypeName()
        ↓
ResponseTypeDescriptor
        ↓
WrapperSchemaProcessor
        ↓
WrapperSchemaEnricher
        ↓
x-data-container-type

This strengthens the OpenAPI Generics metadata model without introducing new response shapes or new reconstruction behavior.


Scope

In scope:

  • Add x-data-container-type
  • Preserve fully qualified Java container identity
  • Extend the existing vendor extension vocabulary
  • Preserve existing List, Set, and Page behavior
  • Maintain backward compatibility
  • Keep existing reconstruction behavior unchanged

Out of scope:

  • Custom container registration
  • New container implementations
  • Arbitrary nested generic support
  • Changes to reconstruction algorithms
  • Changes to extraction strategies
  • Projection of container shape metadata
  • Additional response shapes
  • Introducing a public or projected container shape model

Examples

Existing supported contracts remain unchanged:

ServiceResponse<List<CustomerDto>>

ServiceResponse<Set<CustomerDto>>

ServiceResponse<Page<CustomerDto>>

Equivalent BYOE contracts remain unchanged:

ApiResponse<List<CustomerDto>>

ApiResponse<Set<CustomerDto>>

ApiResponse<Page<CustomerDto>>

Only metadata becomes richer.

Before:

x-data-container: Page
x-data-item: CustomerDto

After:

x-data-container: Page
x-data-container-type: io.github.blueprintplatform.openapi.generics.contract.paging.Page
x-data-item: CustomerDto

Before:

x-data-container: Set
x-data-item: CustomerDto

After:

x-data-container: Set
x-data-container-type: java.util.Set
x-data-item: CustomerDto

Describe alternatives you've considered

Continue using logical container names only

Maintain:

x-data-container: Page

without preserving the actual Java container type.

This keeps metadata smaller but discards information already available during introspection.

Infer container identity from schema names

Attempt to reconstruct container identity from generated schema names.

This introduces unnecessary dependence on naming conventions and weakens determinism.

Project internal container implementation metadata

Expose internal concepts such as extraction strategy, resolver behavior, or container shape through vendor extensions.

This was rejected because those concepts are implementation details of the projection infrastructure and are not required by the external OpenAPI contract.

Store schema shape inside SupportedContainerType

Add projection-specific shape information to the Java container identity model.

This was rejected because SupportedContainerType represents Java-side container identity discovered during introspection.

Schema shape belongs to the projection layer and is already represented by the existing container schema strategies, resolvers, and item extractors.


Expected impact

  • Stronger projection metadata
  • Deterministic container identity
  • Preservation of introspection results
  • Better reconstruction traceability
  • Improved future extensibility
  • Backward-compatible enhancement
  • No change to existing response shape support
  • No change to existing reconstruction behavior

Additional context

This feature does not introduce new capabilities.

List, Set, and Page support already exist.

The purpose of this feature is to preserve information that is already known during response introspection but is currently discarded during OpenAPI projection.

The resulting metadata becomes more explicit while keeping the existing OpenAPI Generics projection and reconstruction model unchanged.



Status

Fixed on main and currently available in 1.2.0-SNAPSHOT.

Planned for the next public release.

Implementation reference:

30614ce

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Fields

No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions