Skip to content

0.8.1 Platform Modularization & Artifact Extraction#16

Merged
bsayli merged 21 commits intomainfrom
feature/0.8.x-generics-platform
Apr 4, 2026
Merged

0.8.1 Platform Modularization & Artifact Extraction#16
bsayli merged 21 commits intomainfrom
feature/0.8.x-generics-platform

Conversation

@bsayli
Copy link
Copy Markdown
Collaborator

@bsayli bsayli commented Apr 4, 2026

🎯 Summary

This PR introduces a system-level architectural redesign that transforms the project from a sample-driven reference implementation into a modular, publishable, contract-driven platform.

This is not a cosmetic refactor.

It establishes:

  • a first-class canonical contract
  • a deterministic OpenAPI projection pipeline
  • a contract-aware client generation model
  • strict architectural boundaries across modules

The previous approach relied on:

  • scattered OpenAPI customization
  • generator-side suppression hacks
  • .openapi-generator-ignore cleanup
  • template patching as a primary control mechanism

These patterns have been removed entirely and replaced with explicit, enforceable architecture.


🧱 Architectural Shift

Before

  • Contract was implicit (api-contract)

  • OpenAPI generation was distributed and non-deterministic

  • Wrapper schemas were injected via customizers scattered across modules

  • Client generation required:

    • ignore rules
    • post-generation cleanup
    • fragile template patching
  • Samples and core logic were tightly coupled

After

  • Contract is a first-class artifact: openapi-generics-contract
  • OpenAPI generation is executed through a single deterministic pipeline
  • Client generation is contract-aware by design
  • Platform is split into independent, versioned modules
  • Samples are external consumers, not part of the runtime

📦 Platform Modules

The system is now structured as:

  • openapi-generics-contract — canonical response model (authority)
  • openapi-generics-platform-bom — dependency alignment
  • openapi-generics-server-starter — OpenAPI projection (Spring Boot integration)
  • openapi-generics-java-codegen — contract-aware generator
  • openapi-generics-java-codegen-parent — build-time orchestration

This establishes clear ownership boundaries:

  • Contract → defines truth
  • Projection (OpenAPI) → deterministic representation
  • Generation → code emission aligned with contract

⚙️ Server-Side Redesign (Projection)

OpenAPI generation is now executed via a single orchestrated pipeline:

Base Schema Registration
→ Discovery (framework-specific)
→ Introspection (contract-aware)
→ Wrapper Processing
→ Ignore Marking
→ Validation (fail-fast)

Key changes:

  • Introduced OpenApiPipelineOrchestrator

  • Eliminated multiple OpenApiCustomizer chains and ordering issues

  • Separated concerns into explicit components:

    • discovery (ResponseTypeDiscoveryStrategy)
    • introspection (ResponseTypeIntrospector)
    • schema processing (WrapperSchemaProcessor)
    • validation (OpenApiContractGuard)

Guarantees

  • Deterministic output → same input produces identical OpenAPI
  • Single execution path → no distributed lifecycle
  • Fail-fast validation → invalid contract state stops generation
  • Framework isolation → MVC/WebFlux differences handled via strategy

🧩 Contract Formalization

The response model is now owned by a dedicated artifact:

openapi-generics-contract

Key elements:

  • ServiceResponse<T>
  • Page<T>
  • Meta, Sort
  • RFC 9457 error model

Vendor Extensions (now first-class DSL)

Contract semantics are expressed via a flat, deterministic extension model:

  • x-api-wrapper
  • x-api-wrapper-datatype
  • x-data-container
  • x-data-item
  • x-ignore-model

Critical Change

x-ignore-model replaces all generator-ignore hacks:

  • Defined at contract/projection level
  • Propagated into OpenAPI
  • Enforced during code generation

This removes the need for:

  • .openapi-generator-ignore
  • post-generation file cleanup
  • import fixing via formatting tools

🔧 Client Generation Redesign

Client generation is now contract-aware, not template-hacked.

Before

  • DTOs were generated and then removed via ignore rules
  • Imports frequently broke → required cleanup (e.g. Spotless)
  • Template patching was fragile and order-dependent

After

  • Contract-owned models are never generated
  • Generator respects x-ignore-model
  • Only thin wrappers are generated
  • Import mappings bind directly to contract types

Generator Behavior

Custom generator: java-generics-contract

  • Phase 1 → mark ignored models
  • Phase 2 → filter locally
  • Phase 3 → remove from global model graph

Result:

  • No duplicate DTOs
  • No cleanup step
  • No formatting hacks
  • Fully deterministic output

🏗️ Build & Tooling Simplification

Introduced

  • openapi-generics-java-codegen-parent

    • encapsulates generator setup
    • standardizes template patching
    • enforces fail-fast behavior

Removed

  • .openapi-generator-ignore
  • DTO cleanup patterns (Page*.java, etc.)
  • Spotless-based import fixes
  • ad-hoc template patching in each project

Build is now:

  • minimal
  • predictable
  • reusable across consumers

🧪 Samples Extraction

Moved to:

/samples

Examples:

  • customer-service
  • customer-service-client

Role change:

  • Before → part of the system
  • After → external consumers validating the platform

🧠 Outcome / Impact

What this enables

  • Maven Central publishing of reusable artifacts
  • Clean separation of responsibilities
  • Deterministic server → OpenAPI → client pipeline
  • Elimination of hidden coupling and hacks

Observable Changes

  • Root build no longer includes samples

  • Consumers depend on:

    • openapi-generics-server-starter
    • openapi-generics-java-codegen-parent
  • Generated clients are thin wrappers over ServiceResponse<T>


🔐 Contract Impact

Impact: yes (formalization, not semantic change)

  • Contract renamed and extracted into openapi-generics-contract
  • Ownership and enforcement are now explicit

No changes to:

  • response envelope structure
  • OpenAPI schema semantics
  • runtime behavior

🌍 Multi‑Language Considerations

  • Platform is Java-first
  • Generator: java-generics-contract

Implications:

  • Vendor extensions are safe no-ops for other languages
  • No fallback templates in this release
  • Multi-language support is out of scope (for now)

❌ Removed Patterns (Intentional)

  • .openapi-generator-ignore based cleanup
  • generator-side DTO suppression hacks
  • scattered OpenAPI customizers
  • implicit contract definitions

These were replaced with explicit architecture and ownership.


✅ Checklist

  • Platform modularization completed
  • Deterministic pipeline implemented
  • Contract formalized as artifact
  • Generator made contract-aware
  • Samples decoupled from runtime
  • Build simplified (no cleanup hacks)
  • Documentation aligned with architecture

🧾 Metadata

Type: refactor
Related Issue: closes #7 (deferred)
Target Release: v0.8.1


💡 Notes for Reviewers

Focus on:

  • module boundaries and ownership
  • pipeline determinism
  • contract enforcement (server → OpenAPI → client)
  • absence of generation hacks

contracts are defined at generation time — not corrected downstream

bsayli added 21 commits March 26, 2026 04:24
…for 0.8.x evolution

This commit introduces the initial architecture decision document for the
OpenAPI Generics Platform evolution line (0.8.x).

The document defines the long-term platform vision and boundaries:

- contract-aware response envelope semantics across server publication and client generation
- deterministic OpenAPI schema composition strategy
- thin generated wrapper model (no DTO envelope duplication)
- SAFE generator orchestration model (pre-generator lifecycle preparation)
- clear scope limitation to supported shapes:
  ServiceResponse<T> and ServiceResponse<Page<T>>

It also formalizes the future modular structure:

- openapi-generics-client-parent
- openapi-generics-java-engine
- openapi-generics-client-starter
- openapi-generics-server-starter

This marks the transition from template-level experimentation
towards a platform-oriented architecture direction.

No functional runtime changes are introduced in this commit.
- add deterministic pipeline (discovery → introspection → schema generation → enrichment)
- register base schemas (ServiceResponse, ServiceResponseVoid, Meta, Sort)
- generate wrapper schemas via allOf composition
- derive schema names from API contract (single source of truth)
- add vendor extensions for wrapper and container semantics
- introduce fail-fast contract validation

OpenAPI is treated as a projection of the API contract.
…chitecture

- replace multiple OpenApiCustomizers with single orchestrated pipeline
- introduce OpenApiPipelineOrchestrator as single execution entry point
- separate concerns into discovery, introspection, processing, and validation stages
- remove implicit Spring ordering in favor of explicit deterministic flow
- enforce fail-fast contract validation
- align OpenAPI generation with contract-as-authority model
- separate wrapper creation vs extension application
- make wrapper factory single source of truth
- remove redundant extension calls in processor
- fix Schema generics usage (avoid raw type warnings)
- enforce required(meta) via setRequired
- keep data optional (contract-aligned)
- ensure deterministic wrapper generation
- validate end-to-end with customer-service
- add BOM and verify integration
…rmatting

- updated architecture and internals docs
- removed unused enforceWrapperExtensions method
- applied Google Java Format
- docs: clarify api-contract as source of truth (OpenAPI = projection)
- build: replace overwrite with changeDetection=always
- add openapi-generics-java-codegen parent
- implement template extraction and patching
- wire customer-service-client to new pipeline
- add x-ignore-model vendor extension for generation control
…t model artifacts

	•	Added GenericAwareJavaCodegen with x-ignore-model support (mark → filter → global prune)
	•	Replaced BaseSchemaIgnoreMarker with SchemaGenerationControlMarker
	•	Automatically ignores dynamic container schemas (e.g. PageCustomerDto) via x-data-container + x-data-item
	•	Removed .openapi-generator-ignore and Spotless-based cleanup
	•	Fixed invalid imports by resolving them at codegen level
	•	Added warning auto-config when Springdoc is missing (prevents silent failure)
	•	Introduced internal platform BOM for version alignment
	•	Verified end-to-end integration (customer-service + client)

Result:
	•	No duplicate model generation
	•	Deterministic output
	•	OpenAPI = projection, Java contract = authority
…re (0.8.x)

- rewrite server-side-adoption.md (minimal, zero-config, contract-first)
- rewrite client-side-adoption.md (thin-wrapper, no duplication model)
- simplify adoption hub (onboarding-first structure)
- fix misleading guidance around response wrappers (payload vs envelope)
- align terminology across server, client, and platform docs
- update samples documentation to reflect canonical usage
- remove outdated lifecycle-heavy explanations

Result:
- consistent mental model across all docs
- clearer onboarding path (60s quick start → rules → mental model)
- strict alignment with contract = authority, OpenAPI = projection
- introduce 2-minute Quick Start aligned with lifecycle flow
- reposition sections for better architectural storytelling
- refine messaging: contract-first, generics-aware boundaries
- improve TOC structure and navigation anchors

docs: minor fixes and renames across architecture documents
- move tagline into hero section
- remove unnecessary divider
- refine spacing and visual hierarchy
…o blueprint-platform namespace

- groupId: io.github.bsayli → io.github.blueprint-platform
- refactor all packages to io.github.blueprintplatform.*
- update modules, aggregator, and documentation
…chitecture

- unify client/server adoption guides
- clarify generation pipeline and boundaries
- improve samples (customer-service, customer-service-client)
- standardize terminology and remove ambiguity
- update compatibility and badges

no functional changes
@bsayli bsayli self-assigned this Apr 4, 2026
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-advanced-security
Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

@bsayli bsayli merged commit b11c875 into main Apr 4, 2026
3 checks passed
@bsayli bsayli deleted the feature/0.8.x-generics-platform branch April 4, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Multi-Language Fallbacks for x-api-wrapper (TypeScript, Kotlin, etc.)

3 participants