Skip to content

Commit b2bad44

Browse files
authored
Merge pull request #8322 from camunda/nicpuppa/client-breaking-change-pagination
docs(api): address breaking changes the java client
2 parents db4997c + 890a287 commit b2bad44

File tree

2 files changed

+73
-1
lines changed

2 files changed

+73
-1
lines changed

docs/apis-tools/migration-manuals/migrate-to-89.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ Review the actions required for the following 8.9 changes:
6868
| <span className="label-highlight red">Breaking change</span> | [Resource deletion endpoint now returns a response body](#resource-deletion) |
6969
| <span className="label-highlight red">Breaking change</span> | [Search filter validation errors now return structured error collections](#search-filter-validation-errors) |
7070
| <span className="label-highlight red">Breaking change</span> | [Spring Boot 4.0 default for Camunda Spring Boot Starter](#spring-boot) |
71+
| <span className="label-highlight red">Breaking change</span> | [Type-safe pagination model in the Camunda Java client](#type-safe-pagination) |
7172
| <span className="label-highlight red">Breaking change</span> | [`versionTag` returns `null` instead of empty string when absent](#version-tag-null) |
72-
| <span className="label-highlight red">Breaking change</span> | [Web Modeler changes](#web-modeler) |
7373
| <span className="label-highlight yellow">Deprecated</span> | [Deprecated: enum literals in Orchestration Cluster API v2](#deprecated-enum) |
7474

7575
## Breaking changes
@@ -431,6 +431,48 @@ If your code parses error response bodies from search endpoints for specific val
431431
- The `detail` field now contains more descriptive, structured messages.
432432
- A collection of validation errors in the response body (instead of a single error message).
433433

434+
### Type-safe pagination model in the Camunda Java client {#type-safe-pagination}
435+
436+
#### Change
437+
438+
The Camunda Java client now uses type-safe pagination interfaces (`AnyPage`, `OffsetPage`, `CursorForwardPage`, `CursorBackwardPage`) instead of the previous `SearchRequestPage` class. Each search or statistics endpoint exposes only the pagination methods it actually supports.
439+
440+
Direction methods on `AnyPage` now return style-specific interfaces: `from()` returns `OffsetPage`, `after()` returns `CursorForwardPage`, and `before()` returns `CursorBackwardPage`. This prevents mixing incompatible pagination styles at compile time.
441+
442+
#### Why
443+
444+
The previous API allowed mixing incompatible pagination styles (for example, `.page(p -> p.from(10).after("cursor"))`), which always resulted in a `400 Bad Request` at runtime. This change surfaces that restriction at compile time. The pattern mirrors the existing sort polymorphism design (`TypedSortableRequest`).
445+
446+
#### Impact
447+
448+
This change is **not binary-compatible**. Code compiled against the previous API will fail at runtime without recompilation, because the method signature changed from `page(Consumer<SearchRequestPage>)` to `page(Consumer<AnyPage>)`. All users must recompile their applications.
449+
450+
Additionally, `TypedSearchRequest` now has 4 generic type parameters (previously 3) and `TypedPageableRequest` now has 2 (previously 1), which is a source-breaking change for custom implementations of these interfaces.
451+
452+
#### Migration reference
453+
454+
| Before (8.8) | After (8.9) |
455+
| :------------------------------------------------- | :---------------------------------------------------------- |
456+
| `import ...search.request.SearchRequestPage` | `import ...search.page.AnyPage` |
457+
| `import ...search.request.SearchRequestOffsetPage` | `import ...search.page.OffsetPage` |
458+
| `Consumer<SearchRequestPage>` | `Consumer<AnyPage>` |
459+
| `Consumer<SearchRequestOffsetPage>` | `Consumer<OffsetPage>` |
460+
| `SearchRequestBuilders.searchRequestPage(fn)` | `SearchRequestBuilders.anyPage(fn)` (old method deprecated) |
461+
| `implements TypedSearchRequest<F, S, Self>` | `implements TypedSearchRequest<F, S, AnyPage, Self>` |
462+
| `implements TypedPageableRequest<Self>` | `implements TypedPageableRequest<AnyPage, Self>` |
463+
| `SearchRequestPage r = p.from(10)` | `OffsetPage r = p.from(10)` |
464+
| `SearchRequestPage r = p.after("c")` | `CursorForwardPage r = p.after("c")` |
465+
466+
#### Action
467+
468+
Update to the latest Java client version and **recompile your application**. If you use inline lambdas with valid pagination patterns (for example, `.page(p -> p.from(5).limit(10))`), your source code does not require changes — but recompilation is mandatory.
469+
470+
If you have explicit references to `SearchRequestPage`, replace them with `AnyPage`. If you store the return value of direction methods (for example, `SearchRequestPage r = p.from(10)`), update the variable type to `OffsetPage`, `CursorForwardPage`, or `CursorBackwardPage` as appropriate.
471+
472+
:::note
473+
This change is specific to the Camunda Java client. Generated clients and custom REST API integrations are not affected.
474+
:::
475+
434476
## Deprecations
435477

436478
Review the actions required for the following deprecations:

docs/reference/announcements-release-notes/890/890-announcements.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,36 @@ Previously, only the first conversion error was returned. This fix improves cons
359359
</div>
360360
<div className="release-announcement-content">
361361

362+
#### Type-safe pagination model in the Camunda Java client
363+
364+
Starting with 8.9.0, the Camunda Java client uses type-safe pagination interfaces (`AnyPage`, `OffsetPage`, `CursorForwardPage`, `CursorBackwardPage`) instead of the previous `SearchRequestPage` class. Each search or statistics endpoint now exposes only the pagination methods it actually supports.
365+
366+
Previously, the API allowed mixing incompatible pagination styles (for example, `.page(p -> p.from(10).after("cursor"))`), which always resulted in a `400 Bad Request` at runtime. This change surfaces that restriction at compile time.
367+
368+
This change is **not binary-compatible**. Code compiled against the old API will fail at runtime without recompilation, because the method signature changed from `page(Consumer<SearchRequestPage>)` to `page(Consumer<AnyPage>)`. All users must recompile, even if their source code does not require changes.
369+
370+
**Action:** Take the following action for your integration type:
371+
372+
| Integration type | Action required |
373+
| :--------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------- |
374+
| Lambda-based pagination (for example, `.page(p -> p.from(5).limit(10))`) | Recompile your application. Source code changes are not required for valid pagination patterns. |
375+
| Explicit `SearchRequestPage` references | Replace with `AnyPage` (import `io.camunda.client.api.search.page.AnyPage`). |
376+
| Explicit `SearchRequestOffsetPage` references | Replace with `OffsetPage`. |
377+
| Custom `TypedSearchRequest` implementations | Add a pagination type parameter (3 → 4 generic params). |
378+
| Custom `TypedPageableRequest` implementations | Add a pagination type parameter (1 → 2 generic params). |
379+
| Storing direction method returns (for example, `SearchRequestPage r = p.from(10)`) | Use `OffsetPage r = p.from(10)`, `CursorForwardPage r = p.after("c")`, or `CursorBackwardPage r = p.before("c")`. |
380+
381+
<p className="link-arrow">[8.9 API migration guide](../../../apis-tools/migration-manuals/migrate-to-89.md#type-safe-pagination)</p>
382+
383+
</div>
384+
</div>
385+
386+
<div className="release-announcement-row">
387+
<div className="release-announcement-badge">
388+
<span className="badge badge--breaking-change">Breaking change</span>
389+
</div>
390+
<div className="release-announcement-content">
391+
362392
#### `versionTag` now returns `null` instead of empty string when absent
363393

364394
Starting with 8.9.0, API response fields for `versionTag` return `null` instead of an empty string `""` when no version tag is set. This properly indicates absence rather than leaking an internal default.

0 commit comments

Comments
 (0)