-
Notifications
You must be signed in to change notification settings - Fork 1
Feature: Modernize API response architecture with RFC 7807 and generics-aware pagination #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…ng support ### customer-service - Implemented CustomerController with full CRUD endpoints for /v1/customers - Added paging, sorting, and search filtering (Page, Meta, Sort abstractions) - Introduced CustomerControllerAdvice for centralized RFC 7807 ProblemDetail error handling (400, 404, 500, validation, and type mismatch scenarios) - Improved error payloads with requestId, errorCode, and violations list - Updated CustomerServiceImpl with in-memory data store, pagination, and sorting logic ### customer-service-client - Refactored OpenAPI templates (pojo.mustache / model.mustache) to cleanly handle additionalProperties imports via vendorExtensions - Ensured generated ProblemDetail model conforms to RFC 7807 schema - Added GlobalErrorResponsesCustomizer to inject shared problem+json responses (400, 404, 500) into all OpenAPI operations - Unified schema references, imports, and codegen stability between client and server Overall: standardized API behavior, improved OpenAPI alignment, and ensured type-safe client generation with consistent error and response contracts.
…cs-aware client generation
# Server (customer-service)
- Add uniform RFC7807 error handling:
- Introduced layered @RestControllerAdvice handlers:
- ValidationExceptionHandler (400, field errors, constraint violations)
- JsonExceptionHandler (400, unreadable/invalid JSON, unrecognized fields)
- SpringHttpExceptionHandler (404/405/400 parameter issues)
- ApplicationExceptionHandler (404 domain not-found, 500 fallback)
- Centralized helpers in `ProblemSupport` (type URIs, baseProblem, attachErrors).
- Added `ErrorItem` and `ProblemExtensions` records for structured error payloads.
- OpenAPI enrichment for errors:
- `GlobalErrorResponsesCustomizer` injects 400/404/405/500 responses with `application/problem+json`.
- Ensures `ProblemDetail` + `ErrorItem` schemas present (component-level).
- Common response model improvements:
- `Page<T>` record (content, page, size, totals, hasNext/Prev).
- `Meta` record (requestId, serverTime, sort) with helpers.
- Constants and extension keys moved under `OpenApiSchemas`.
# OpenAPI (server-side generation metadata)
- Auto-register type-safe wrappers:
- `AutoWrapperSchemaCustomizer` scans controller return types and adds composed
`ServiceResponse<...>` wrappers into components.
- Enriches wrappers with vendor extensions:
- `x-api-wrapper`, `x-api-wrapper-datatype`
- `x-data-container` (e.g., `Page`) and `x-data-item` (e.g., `CustomerDto`)
- Robust resolution for `$ref`, `allOf`, and array `items` (handles 3.1 `JsonSchema`).
- Standardized extension constants in `OpenApiSchemas`.
# Client (customer-service-client)
- Strongly-typed core:
- Introduced records:
- `Page<T>` (immutable `content` defensive copy)
- `ClientMeta` (immutable copy of sort list)
- Sort model under `common.sort` package:
- `SortField` (CUSTOMER_ID/NAME/EMAIL) and `SortDirection` (ASC/DESC) enums
- `ClientSort` record (defaults to CUSTOMER_ID/ASC)
- Generic response base kept as class (for extension):
- `ServiceClientResponse<T>` unchanged intentionally (can be subclassed by generated wrappers).
- Generics-aware template for generated wrappers:
- If `x-data-container` & `x-data-item` exist, generate
`extends ServiceClientResponse<Container<Item>>`
- Else fallback to `extends ServiceClientResponse<Datatype>`
- Error translation for RestClient:
- `ClientProblemException` (Serializable) wraps RFC7807 body + HTTP status.
- `CustomerApiClientConfig` registers `RestClientCustomizer` that reads `ProblemDetail`
from response and throws `ClientProblemException` for any non-2xx.
- Manual application of `RestClientCustomizer`s when building `ApiClient` (test-friendly).
- Adapter API made type-safe:
- `getCustomers(..)` now accepts `SortField` / `SortDirection` instead of raw strings,
adapts to generated wire-level params seamlessly.
# Tests
- Unit: `CustomerClientAdapterImplTest` updated for records and typed Page.
- Integration (MockWebServer):
- `CustomerClientIT` happy-path tests for 201/200 and Page mapping.
- `CustomerClientErrorIT` error-path tests:
- 404 with ProblemDetail
- 400 validation problem (extensions.errors)
- 500 without body (null ProblemDetail fallback)
- New unit tests for config error handler (object mapper parse + no-body case).
BREAKING CHANGES:
- Client adapter signature change:
- `getCustomers(name, email, page, size, sortBy, direction: String)` ➜
`getCustomers(name, email, page, size, sortBy: SortField, direction: SortDirection)`
- Generated DTO envelope classes now extend `ServiceClientResponse<...>` using container/item
metadata; downstream code relying on previous raw wrapper generics may require minor updates.
- Sort model moved under `io.github.bsayli.openapi.client.common.sort`.
Refs:
- OpenAPI 3.1 compose/resolve support (array item `$ref`, `JsonSchema`).
- RFC7807 consistent error payloads end-to-end.
…ested generics architecture
### Why
The previous documentation described only `ServiceResponse<T>` without the new meta layer and nested generic support.
### What Changed
- Updated root README to introduce the `{ data, meta }` response structure
- Added details about full nested generic handling (`ServiceResponse<Page<T>>`)
- Revised adoption guides (server & client) to match new architecture
- Clarified OpenAPI extensions (`x-api-wrapper`, `x-data-container`, `x-data-item`)
- Improved Quick Start and examples to reflect current generator output
### Result
All docs now reflect the latest end-to-end generics-aware design and align with the production-ready OpenAPI Generator 7.16.0 setup.
… RFC 7807 alignment
- Rewrote root README.md with modern architectural overview, response flow diagram, and end-to-end example
- Updated all adoption guides under /docs/adoption:
- server-side-adoption.md → now includes {data, meta} envelope and optional Problem extensions
- client-side-adoption.md → fully refactored for RFC 7807 ProblemDetail decoding and RestClient integration
- client-side-adoption-pom.md → clarified Maven plugin chain, properties, and new additionalProperties syntax
- Added consistent formatting, section numbering, and Google-style code blocks
- Unified terminology: “ServiceResponse<T> / ServiceClientResponse<T>” and “Meta” across all examples
- Refined OpenAPI 3.1 alignment (springdoc 2.8.13, generator 7.16.0, HttpClient5 5.5)
- Introduced clean architecture diagram for end-to-end client generation flow
- Improved readability and SEO structure for GitHub Pages rendering
Result: project docs now reflect the final {data, meta} response model, nested generics support, and full ProblemDetail compliance.
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment Thanks for integrating Codecov - We've got you covered ☂️ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
feat: modernize API response architecture with RFC 7807, dynamic generics, and pagination-aware wrappers
Closes #4 — Adopt RFC 7807 (application/problem+json) for standardized error responses
Closes #5 — Introduce generic Page schema and pagination-aware ServiceResponse wrappers
Summary:
AutoWrapperSchemaCustomizer) for runtime schema enrichmentProblemDetailand consistent client decodingapplication.yamlconfiguration to support multiple generic container types (Page, Slice, etc.)app.openapi.wrapper.*propertiesResult:
The project now features a fully dynamic generics-aware OpenAPI schema layer, enabling true nested type support, RFC 7807 error compliance, and pagination-ready response envelopes.