Skip to content

Commit 3e81546

Browse files
committed
test(samples): add transport compatibility coverage
1 parent 4088dfe commit 3e81546

33 files changed

Lines changed: 1702 additions & 334 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ This project follows a contract-first release discipline:
1616

1717
OpenAPI Generics 1.2.1 simplifies contract-driven wrapper reconstruction by making the generated OpenAPI document the single source of truth for envelope identity.
1818

19-
This release removes redundant client-side envelope configuration, completes end-to-end validation for application-defined generic containers with the built-in `ServiceResponse<T>` envelope, and continues platform verification and dependency alignment without changing runtime behavior.
19+
This release removes redundant client-side envelope configuration, completes end-to-end validation for application-defined generic containers with the built-in `ServiceResponse<T>` envelope, and expands platform verification across contract reconstruction, framework compatibility, and standard HTTP transport behavior without changing runtime behavior.
2020

2121
### Added
2222

2323
- Added the `x-api-wrapper-type` vendor extension to preserve the fully qualified Java envelope type in projected wrapper schemas.
2424
- Added contract-driven envelope reconstruction in the Java code generator based on `x-api-wrapper-type`.
2525
- Added end-to-end validation for application-defined generic containers used with the built-in `ServiceResponse<T>` envelope.
2626
- Expanded sample coverage for producer → OpenAPI → generated client → consumer validation using application-owned generic containers.
27+
- Added a dedicated `transport-coverage` sample for multipart upload, binary download, and form-urlencoded compatibility with the Java RestClient generator.
2728

2829
### Changed
2930

@@ -44,6 +45,11 @@ This release removes redundant client-side envelope configuration, completes end
4445
- Added verification that generated clients reconstruct wrapper inheritance without client-side envelope configuration.
4546
- Verified built-in `ServiceResponse<T>` and BYOE envelope generation using the same metadata-driven reconstruction pipeline.
4647
- Verified producer → OpenAPI → generated client → consumer flows after removing redundant client-side envelope configuration.
48+
- Added transport regression coverage for `multipart/form-data`, `application/octet-stream`, and `application/x-www-form-urlencoded`.
49+
- Verified that standard OpenAPI Generator Java RestClient transport behavior remains intact while generic JSON response reconstruction is enabled.
50+
- Verified multipart file plus structured JSON part generation together with `ServiceResponse<T>` reconstruction.
51+
- Verified binary download generation using the standard Spring `Resource` abstraction without wrapper interference.
52+
- Verified form-urlencoded request generation together with generic response reconstruction.
4753
- Verified the Spring Boot 4 integration stack on Spring Boot 4.1.0, Springdoc 3.1.0, and Java 25 LTS.
4854
- Verified mixed Java baselines with Java 21 for Spring Boot 3 samples and Java 25 for Spring Boot 4 samples while published platform artifacts continue targeting Java 17+.
4955

samples/README.md

Lines changed: 85 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ Consumer Service
2020

2121
The generated client reconstructs the original contract shape instead of redefining equivalent wrapper models.
2222

23-
---
24-
2523
## Table of Contents
2624

2725
- [Overview](#overview)
@@ -31,31 +29,28 @@ The generated client reconstructs the original contract shape instead of redefin
3129
- [Spring Boot 3 Stack](#spring-boot-3-stack)
3230
- [Spring Boot 4 Stack](#spring-boot-4-stack)
3331
- [Type Coverage Samples](#type-coverage-samples)
32+
- [Transport Coverage Sample](#transport-coverage-sample)
3433
- [Local Maven Build](#local-maven-build)
3534
- [What to Observe](#what-to-observe)
3635
- [Notes](#notes)
3736
- [Summary](#summary)
3837

39-
---
40-
4138
## Overview
4239

4340
Each runnable integration stack contains three layers:
4441

45-
| Layer | Responsibility |
46-
|----------------------|--------------------------------------------------------------------------|
47-
| **Producer** | Defines the Java API contract and publishes the OpenAPI document. |
48-
| **Generated client** | Is generated from the OpenAPI document using OpenAPI Generics. |
49-
| **Consumer** | Uses the generated client and exposes downstream verification endpoints. |
42+
| Layer | Responsibility |
43+
| --- | --- |
44+
| **Producer** | Defines the Java API contract and publishes the OpenAPI document. |
45+
| **Generated client** | Is generated from the OpenAPI document using OpenAPI Generics. |
46+
| **Consumer** | Uses the generated client and exposes downstream verification endpoints. |
5047

5148
The same contract moves through all layers.
5249

5350
No manual wrapper reconstruction is required in the consumer.
5451

5552
No DTO translation layer is required between producer and consumer.
5653

57-
---
58-
5954
## Sample Layout
6055

6156
```text
@@ -69,34 +64,35 @@ samples
6964
│ ├── customer-service
7065
│ ├── customer-service-client
7166
│ └── customer-service-consumer
72-
└── type-coverage
73-
├── service-response
74-
└── byoe-response
67+
├── type-coverage
68+
│ ├── service-response
69+
│ └── byoe-response
70+
└── transport-coverage
7571
```
7672

77-
| Directory | Purpose |
78-
|--------------------|------------------------------------------------------------------------------------------|
79-
| `domain-contracts` | Shared domain and contract types used by the sample stacks. |
80-
| `spring-boot-3` | Runnable Spring Boot 3 producer → generated client → consumer stack. |
81-
| `spring-boot-4` | Runnable Spring Boot 4 producer → generated client → consumer stack. |
82-
| `type-coverage` | Focused validation suites for supported generic response shapes and regression coverage. |
83-
84-
---
73+
| Directory | Purpose |
74+
| --- | --- |
75+
| `domain-contracts` | Shared domain and contract types used by the sample stacks. |
76+
| `spring-boot-3` | Runnable Spring Boot 3 producer → generated client → consumer stack. |
77+
| `spring-boot-4` | Runnable Spring Boot 4 producer → generated client → consumer stack. |
78+
| `type-coverage` | Focused validation suites for supported generic response shapes and regression coverage. |
79+
| `transport-coverage` | Focused validation suite for transport compatibility and regression coverage. |
8580

8681
## Available Sample Types
8782

88-
The repository contains two kinds of samples.
83+
The repository contains three kinds of samples.
8984

90-
| Sample Type | Purpose |
91-
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
92-
| **Integration stacks** | Runnable producer → generated client → consumer applications for Spring Boot 3 and Spring Boot 4. |
93-
| **Type coverage samples** | Focused regression suites that validate supported generic response shapes, BYOE contracts, collections, pages, and application-owned generic containers. |
85+
| Sample Type | Purpose |
86+
| --- | --- |
87+
| **Integration stacks** | Runnable producer → generated client → consumer applications for Spring Boot 3 and Spring Boot 4. |
88+
| **Type coverage samples** | Focused regression suites validating generic response reconstruction across supported contract shapes. |
89+
| **Transport coverage sample** | Focused regression suite validating standard HTTP transport compatibility together with generic response reconstruction. |
9490

9591
The integration stacks are intended for first-time users who want to run the platform end-to-end.
9692

97-
The type coverage samples are intended for validating the core OpenAPI Generics reconstruction pipeline across many response shapes.
93+
The type-coverage samples validate the core OpenAPI Generics reconstruction pipeline across many response shapes.
9894

99-
---
95+
The transport-coverage sample validates that the custom `java-generics-contract` generator remains compatible with standard OpenAPI Generator transport behavior.
10096

10197
## Prerequisites
10298

@@ -107,10 +103,12 @@ For Docker-based sample execution:
107103

108104
For local Maven builds:
109105

110-
- Java 17+
106+
- Java 25
111107
- Maven 3.9+
112108

113-
---
109+
The sample suite includes both Java 21 and Java 25 modules. Building the complete `samples` reactor therefore requires JDK 25.
110+
111+
Published OpenAPI Generics platform artifacts continue to target Java 17+.
114112

115113
## Spring Boot 3 Stack
116114

@@ -130,15 +128,13 @@ Spring Boot 3 Consumer
130128

131129
### Services
132130

133-
| Service | Port | URL |
134-
|----------|------|---------------------------------------------------|
135-
| Producer | 8084 | `http://localhost:8084/customer-service` |
136-
| Consumer | 8085 | `http://localhost:8085/customer-service-consumer` |
131+
| Service | Port |
132+
| --- | ---: |
133+
| Producer | 8084 |
134+
| Consumer | 8085 |
137135

138136
### Start
139137

140-
From the `samples` directory:
141-
142138
```bash
143139
cd spring-boot-3
144140
docker compose up --build -d
@@ -160,14 +156,10 @@ http://localhost:8084/customer-service/swagger-ui/index.html
160156

161157
### Verify Consumer
162158

163-
Single resource:
164-
165159
```bash
166160
curl http://localhost:8085/customer-service-consumer/customers/1
167161
```
168162

169-
Paginated response:
170-
171163
```bash
172164
curl "http://localhost:8085/customer-service-consumer/customers?page=0&size=5"
173165
```
@@ -178,19 +170,15 @@ The response should preserve the same contract shape across producer, OpenAPI, g
178170

179171
### Stop
180172

181-
From the `samples/spring-boot-3` directory:
182-
183173
```bash
184174
docker compose down
185175
```
186176

187-
---
188-
189177
## Spring Boot 4 Stack
190178

191179
Use this stack when validating the Spring Boot 4 runtime path.
192180

193-
It runs the same OpenAPI Generics lifecycle as the Spring Boot 3 stack, but on the Spring Boot 4 baseline:
181+
It runs the same lifecycle:
194182

195183
```text
196184
Spring Boot 4 Producer
@@ -204,15 +192,13 @@ Spring Boot 4 Consumer
204192

205193
### Services
206194

207-
| Service | Port | URL |
208-
|----------|------|---------------------------------------------------|
209-
| Producer | 8094 | `http://localhost:8094/customer-service` |
210-
| Consumer | 8095 | `http://localhost:8095/customer-service-consumer` |
195+
| Service | Port |
196+
| --- | ---: |
197+
| Producer | 8094 |
198+
| Consumer | 8095 |
211199

212200
### Start
213201

214-
From the `samples` directory:
215-
216202
```bash
217203
cd spring-boot-4
218204
docker compose up --build -d
@@ -234,79 +220,83 @@ http://localhost:8094/customer-service/swagger-ui/index.html
234220

235221
### Verify Consumer
236222

237-
Single resource:
238-
239223
```bash
240224
curl http://localhost:8095/customer-service-consumer/customers/1
241225
```
242226

243-
Paginated response:
244-
245227
```bash
246228
curl "http://localhost:8095/customer-service-consumer/customers?page=0&size=5"
247229
```
248230

249231
The behavior is intentionally equivalent to the Spring Boot 3 stack.
250232

251-
The purpose is to verify that the same OpenAPI Generics contract flow works across the Spring Boot 4 runtime baseline.
252-
253233
### Stop
254234

255-
From the `samples/spring-boot-4` directory:
256-
257235
```bash
258236
docker compose down
259237
```
260238

261-
---
262-
263239
## Type Coverage Samples
264240

265241
The `type-coverage` directory contains focused validation suites for the core OpenAPI Generics reconstruction pipeline.
266242

267243
Unlike the Spring Boot integration stacks, these samples are not intended to demonstrate application architecture or business workflows.
268244

269-
They verify contract-preservation behavior across supported response shapes, including:
245+
They validate contract preservation across supported response shapes, including:
270246

271247
- scalar payloads
272248
- value payloads
273249
- enum payloads
274250
- DTO payloads
275-
- `List<T>` payloads
276-
- `Set<T>` payloads
277-
- built-in `Page<T>` payloads
278-
- application-owned generic containers such as `Paging<T>` and `Window<T>`
279-
- platform-owned `ServiceResponse<T>` envelopes
280-
- user-owned BYOE `ApiResponse<T>` envelopes
251+
- `List<T>`
252+
- `Set<T>`
253+
- built-in `Page<T>`
254+
- application-owned generic containers
255+
- platform-owned `ServiceResponse<T>`
256+
- user-owned BYOE `ApiResponse<T>`
281257

282-
Available type-coverage samples:
258+
Available samples:
283259

284-
| Sample | Purpose |
285-
|----------------------------------|-----------------------------------------------------------------------------------------|
286-
| `type-coverage/service-response` | Validates the canonical platform-provided `ServiceResponse<T>` contract. |
287-
| `type-coverage/byoe-response` | Validates Bring Your Own Envelope support using a user-owned `ApiResponse<T>` contract. |
260+
| Sample | Purpose |
261+
| --- | --- |
262+
| `type-coverage/service-response` | Validates the platform-provided `ServiceResponse<T>` contract. |
263+
| `type-coverage/byoe-response` | Validates Bring Your Own Envelope using a user-owned `ApiResponse<T>` contract. |
288264

289-
These samples are used as executable regression suites for projection metadata, vendor extensions, wrapper reconstruction, generated client typing, runtime deserialization, and consumer compatibility.
265+
See [`type-coverage/README.md`](type-coverage/README.md) for the complete validation matrix.
290266

291-
See [`type-coverage/README.md`](type-coverage/README.md) for the full validation matrix.
267+
## Transport Coverage Sample
292268

293-
---
269+
The `transport-coverage` directory validates that OpenAPI Generics remains transport-neutral.
294270

295-
## Local Maven Build
271+
Rather than introducing new transport behavior, it verifies that the custom `java-generics-contract` generator preserves the standard transport functionality provided by the upstream Java RestClient generator.
272+
273+
The initial transport matrix covers:
296274

297-
Docker is the recommended path for running the integration stacks.
275+
- `multipart/form-data`
276+
- `application/octet-stream`
277+
- `application/x-www-form-urlencoded`
298278

299-
For local build verification, run from the `samples` directory:
279+
while simultaneously validating generic response reconstruction where JSON responses are returned.
280+
281+
Available sample:
282+
283+
| Sample | Purpose |
284+
| --- | --- |
285+
| `transport-coverage` | Validates transport compatibility together with generic response reconstruction. |
286+
287+
See [`transport-coverage/README.md`](transport-coverage/README.md) for transport scenarios, validation flow, and regression scope.
288+
289+
## Local Maven Build
290+
291+
From the `samples` directory:
300292

301293
```bash
302294
mvn clean install
303295
```
304296

305-
This builds the sample modules and verifies that generated client artifacts compile successfully.
306-
307-
Individual services can also be started locally from their module directories when needed.
297+
This builds every sample module and verifies that generated client artifacts compile successfully.
308298

309-
---
299+
Individual services can also be started directly from their module directories when needed.
310300

311301
## What to Observe
312302

@@ -324,7 +314,7 @@ Observe that:
324314
- paginated generic responses keep their generic structure
325315
- generated wrappers extend reusable contract types instead of redefining equivalent models
326316

327-
For example, generated response wrappers should remain thin contract bindings rather than duplicated envelope implementations:
317+
For example:
328318

329319
```java
330320
public class ServiceResponsePageCustomerDto
@@ -335,25 +325,26 @@ The generated class binds the generic parameters.
335325

336326
It does not become the owner of the envelope structure.
337327

338-
---
339-
340328
## Notes
341329

342330
- Samples use in-memory data.
343331
- No external database is required.
344332
- The sample domain is intentionally simple.
345-
- The focus is contract projection, generated client reconstruction, and downstream reuse.
346333
- Spring Boot 3 and Spring Boot 4 stacks are intentionally equivalent.
347-
- Type-coverage samples provide focused regression validation beyond the customer-service integration flow.
348-
- You do not need to run the Spring Boot 3 and Spring Boot 4 stacks at the same time.
349-
350-
---
334+
- Type-coverage samples validate generic reconstruction across supported contract shapes.
335+
- Transport-coverage validates compatibility with standard OpenAPI Generator transport behavior.
336+
- You do not need to run every sample simultaneously.
351337

352338
## Summary
353339

354340
These samples provide runnable environments for validating the OpenAPI Generics contract lifecycle.
355341

356-
They prove that a Java contract can be projected into OpenAPI, reconstructed into a generated Java client, and reused by a downstream consumer without redefining equivalent wrapper or DTO models.
342+
Together they demonstrate:
343+
344+
- end-to-end producer → generated client → consumer integration
345+
- generic response reconstruction
346+
- Bring Your Own Envelope (BYOE)
347+
- transport compatibility with standard OpenAPI Generator behavior
357348

358349
```text
359350
Java Contract
@@ -365,4 +356,4 @@ Generated Client
365356
Consumer Reuse
366357
```
367358

368-
The result is stable contract identity across service boundaries.
359+
The result is stable contract identity across service boundaries while preserving both generic semantics and standard transport behavior.

samples/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<module>spring-boot-3</module>
3131
<module>spring-boot-4</module>
3232
<module>type-coverage</module>
33+
<module>transport-coverage</module>
3334
</modules>
3435
<build>
3536
<pluginManagement>

0 commit comments

Comments
 (0)