Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
23 changes: 13 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
- next
branches-ignore:
- 'generated'
- 'codegen/**'
- 'integrated/**'
- 'stl-preview-head/**'
- 'stl-preview-base/**'

jobs:
lint:
timeout-minutes: 10
name: lint
runs-on: ubuntu-latest
runs-on: ${{ github.repository == 'stainless-sdks/orb-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}

steps:
- uses: actions/checkout@v4

Expand All @@ -21,7 +23,7 @@ jobs:
distribution: temurin
java-version: |
8
17
21
cache: gradle

- name: Set up Gradle
Expand All @@ -30,8 +32,9 @@ jobs:
- name: Run lints
run: ./scripts/lint
test:
timeout-minutes: 10
name: test
runs-on: ubuntu-latest
runs-on: ${{ github.repository == 'stainless-sdks/orb-java' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4

Expand All @@ -41,7 +44,7 @@ jobs:
distribution: temurin
java-version: |
8
17
21
cache: gradle

- name: Set up Gradle
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-sonatype.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
export -- GPG_SIGNING_KEY_ID
printenv -- GPG_SIGNING_KEY | gpg --batch --passphrase-fd 3 --import 3<<< "$GPG_SIGNING_PASSWORD"
GPG_SIGNING_KEY_ID="$(gpg --with-colons --list-keys | awk -F : -- '/^pub:/ { getline; print "0x" substr($10, length($10) - 7) }')"
./gradlew publishAndReleaseToMavenCentral --stacktrace -PmavenCentralUsername="$SONATYPE_USERNAME" -PmavenCentralPassword="$SONATYPE_PASSWORD"
./gradlew publishAndReleaseToMavenCentral --stacktrace -PmavenCentralUsername="$SONATYPE_USERNAME" -PmavenCentralPassword="$SONATYPE_PASSWORD" --no-configuration-cache
env:
SONATYPE_USERNAME: ${{ secrets.ORB_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }}
SONATYPE_PASSWORD: ${{ secrets.ORB_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }}
Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.56.0"
".": "0.57.0"
}
2 changes: 1 addition & 1 deletion .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 106
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-e8dad7eee5621fe2ba948dfd00dabf170d9d92ce615a9f04b0f546f4d8bf39ba.yml
openapi_spec_hash: 3f6a98e3a1b3a47acebd67a960090ebf
config_hash: 7e523cf79552b8936bd772f2e1025e5f
config_hash: f6da12790e8f46d93592def474d41c69
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,58 @@
# Changelog

## 0.57.0 (2025-05-22)

Full Changelog: [v0.56.0...v0.57.0](https://github.com/orbcorp/orb-java/compare/v0.56.0...v0.57.0)

### ⚠ BREAKING CHANGES

* **client:** improve some class names
* **client:** extract auto pagination to shared classes
* **client:** **Migration:** - If you were referencing the `AutoPager` class on a specific `*Page` or `*PageAsync` type, then you should instead reference the shared `AutoPager` and `AutoPagerAsync` types, under the `core` package
- `AutoPagerAsync` now has different usage. You can call `.subscribe(...)` on the returned object instead to get called back each page item. You can also call `onCompleteFuture()` to get a future that completes when all items have been processed. Finally, you can call `.close()` on the returned object to stop auto-paginating early
- If you were referencing `getNextPage` or `getNextPageParams`:
- Swap to `nextPage()` and `nextPageParams()`
- Note that these both now return non-optional types (use `hasNextPage()` before calling these, since they will throw if it's impossible to get another page)

### Features

* **client:** allow providing some params positionally ([7ddd872](https://github.com/orbcorp/orb-java/commit/7ddd872ee4fb49e2e3f4b6d5938bc9a5ed0e2342))
* **client:** extract auto pagination to shared classes ([9affbde](https://github.com/orbcorp/orb-java/commit/9affbdee875bdf75fa150d58ed8de23b9d51eaf2))


### Bug Fixes

* **internal:** fix name collision errors from Unit import ([1f7beef](https://github.com/orbcorp/orb-java/commit/1f7beefa05c6cb1356d1973bbcb0955f7eb65fbd))


### Performance Improvements

* **internal:** improve compilation+test speed ([f72c4ad](https://github.com/orbcorp/orb-java/commit/f72c4ad7c4604330f2ff972b517b2e3f03f5356f))


### Chores

* **ci:** only use depot for staging repos ([68dcdd8](https://github.com/orbcorp/orb-java/commit/68dcdd85f1eac797fae1136e383afae1ad5c0e28))
* **ci:** run on more branches and use depot runners ([ddcc77e](https://github.com/orbcorp/orb-java/commit/ddcc77e1835fe8ec200fbfeb5d0427ef19fb6d25))
* **docs:** grammar improvements ([7b5fb07](https://github.com/orbcorp/orb-java/commit/7b5fb07cdbe4b1ac8f41d95de243b913fce60a13))
* **internal:** codegen related update ([9df208b](https://github.com/orbcorp/orb-java/commit/9df208bf6cf18c90cc09bf1f3eba9ba1e5b4c767))
* **internal:** codegen related update ([7db8db6](https://github.com/orbcorp/orb-java/commit/7db8db63862be728dc201e36aa3ff164307c5e4e))
* **internal:** java 17 -&gt; 21 on ci ([7f2fb10](https://github.com/orbcorp/orb-java/commit/7f2fb1063cd794a4c46fb88203944d4262a0a1db))
* **internal:** remove flaky `-Xbackend-threads=0` option ([b085373](https://github.com/orbcorp/orb-java/commit/b085373fc56676f510a0b0900e8cecd2af633313))
* **internal:** update java toolchain ([2b4abdf](https://github.com/orbcorp/orb-java/commit/2b4abdff056e4bd158c6a2bc605c4ba09e4760d0))


### Documentation

* **client:** update jackson compat error message ([b3ceb27](https://github.com/orbcorp/orb-java/commit/b3ceb2741476209419bd210d7caebec7fbb5eaa7))
* explain http client customization ([31827ac](https://github.com/orbcorp/orb-java/commit/31827acf060986c871832a7619f09dae7aab1640))
* explain jackson compat in readme ([fb2505d](https://github.com/orbcorp/orb-java/commit/fb2505d8cdf9fb61589715396da17d424de5f7c0))


### Refactors

* **client:** improve some class names ([9460c52](https://github.com/orbcorp/orb-java/commit/9460c523ec5235f4b8b6335336be8e3b82b8527f))

## 0.56.0 (2025-04-09)

Full Changelog: [v0.55.0...v0.56.0](https://github.com/orbcorp/orb-java/compare/v0.55.0...v0.56.0)
Expand Down
137 changes: 115 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<!-- x-release-please-start-version -->

[![Maven Central](https://img.shields.io/maven-central/v/com.withorb.api/orb-java)](https://central.sonatype.com/artifact/com.withorb.api/orb-java/0.56.0)
[![Maven Central](https://img.shields.io/maven-central/v/com.withorb.api/orb-java)](https://central.sonatype.com/artifact/com.withorb.api/orb-java/0.57.0)

<!-- x-release-please-end -->

Expand All @@ -19,7 +19,7 @@ The REST API documentation can be found on [docs.withorb.com](https://docs.witho
### Gradle

```kotlin
implementation("com.withorb.api:orb-java:0.56.0")
implementation("com.withorb.api:orb-java:0.57.0")
```

### Maven
Expand All @@ -28,7 +28,7 @@ implementation("com.withorb.api:orb-java:0.56.0")
<dependency>
<groupId>com.withorb.api</groupId>
<artifactId>orb-java</artifactId>
<version>0.56.0</version>
<version>0.57.0</version>
</dependency>
```

Expand Down Expand Up @@ -215,53 +215,101 @@ The SDK throws custom unchecked exception types:

## Pagination

For methods that return a paginated list of results, this library provides convenient ways access the results either one page at a time, or item-by-item across all pages.
The SDK defines methods that return a paginated lists of results. It provides convenient ways to access the results either one page at a time or item-by-item across all pages.

### Auto-pagination

To iterate through all results across all pages, you can use `autoPager`, which automatically handles fetching more pages for you:
To iterate through all results across all pages, use the `autoPager()` method, which automatically fetches more pages as needed.

### Synchronous
When using the synchronous client, the method returns an [`Iterable`](https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html)

```java
import com.withorb.api.models.Coupon;
import com.withorb.api.models.CouponListPage;

// As an Iterable:
CouponListPage page = client.coupons().list(params);
CouponListPage page = client.coupons().list();

// Process as an Iterable
for (Coupon coupon : page.autoPager()) {
System.out.println(coupon);
};
}

// As a Stream:
client.coupons().list(params).autoPager().stream()
// Process as a Stream
page.autoPager()
.stream()
.limit(50)
.forEach(coupon -> System.out.println(coupon));
```

### Asynchronous
When using the asynchronous client, the method returns an [`AsyncStreamResponse`](orb-java-core/src/main/kotlin/com/withorb/api/core/http/AsyncStreamResponse.kt):

```java
// Using forEach, which returns CompletableFuture<Void>:
asyncClient.coupons().list(params).autoPager()
.forEach(coupon -> System.out.println(coupon), executor);
import com.withorb.api.core.http.AsyncStreamResponse;
import com.withorb.api.models.Coupon;
import com.withorb.api.models.CouponListPageAsync;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

CompletableFuture<CouponListPageAsync> pageFuture = client.async().coupons().list();

pageFuture.thenRun(page -> page.autoPager().subscribe(coupon -> {
System.out.println(coupon);
}));

// If you need to handle errors or completion of the stream
pageFuture.thenRun(page -> page.autoPager().subscribe(new AsyncStreamResponse.Handler<>() {
@Override
public void onNext(Coupon coupon) {
System.out.println(coupon);
}

@Override
public void onComplete(Optional<Throwable> error) {
if (error.isPresent()) {
System.out.println("Something went wrong!");
throw new RuntimeException(error.get());
} else {
System.out.println("No more!");
}
}
}));

// Or use futures
pageFuture.thenRun(page -> page.autoPager()
.subscribe(coupon -> {
System.out.println(coupon);
})
.onCompleteFuture()
.whenComplete((unused, error) -> {
if (error != null) {
System.out.println("Something went wrong!");
throw new RuntimeException(error);
} else {
System.out.println("No more!");
}
}));
```

### Manual pagination

If none of the above helpers meet your needs, you can also manually request pages one-by-one. A page of results has a `data()` method to fetch the list of objects, as well as top-level `response` and other methods to fetch top-level data about the page. It also has methods `hasNextPage`, `getNextPage`, and `getNextPageParams` methods to help with pagination.
To access individual page items and manually request the next page, use the `items()`,
`hasNextPage()`, and `nextPage()` methods:

```java
import com.withorb.api.models.Coupon;
import com.withorb.api.models.CouponListPage;

CouponListPage page = client.coupons().list(params);
while (page != null) {
for (Coupon coupon : page.data()) {
CouponListPage page = client.coupons().list();
while (true) {
for (Coupon coupon : page.items()) {
System.out.println(coupon);
}

page = page.getNextPage().orElse(null);
if (!page.hasNextPage()) {
break;
}

page = page.nextPage();
}
```

Expand Down Expand Up @@ -291,6 +339,17 @@ both of which will raise an error if the signature is invalid.
Note that the `body` parameter must be the raw JSON string sent from the server (do not parse it first).
The `.unwrap()` method can parse this JSON for you.

## Jackson

The SDK depends on [Jackson](https://github.com/FasterXML/jackson) for JSON serialization/deserialization. It is compatible with version 2.13.4 or higher, but depends on version 2.18.2 by default.

The SDK throws an exception if it detects an incompatible Jackson version at runtime (e.g. if the default version was overridden in your Maven or Gradle config).

If the SDK threw an exception, but you're _certain_ the version is compatible, then disable the version check using the `checkJacksonVersionCompatibility` on [`OrbOkHttpClient`](orb-java-client-okhttp/src/main/kotlin/com/withorb/api/client/okhttp/OrbOkHttpClient.kt) or [`OrbOkHttpClientAsync`](orb-java-client-okhttp/src/main/kotlin/com/withorb/api/client/okhttp/OrbOkHttpClientAsync.kt).

> [!CAUTION]
> We make no guarantee that the SDK works correctly when the Jackson version check is disabled.

## Network options

### Retries
Expand Down Expand Up @@ -327,7 +386,6 @@ To set a custom timeout, configure the method call using the `timeout` method:

```java
import com.withorb.api.models.Customer;
import com.withorb.api.models.CustomerCreateParams;

Customer customer = client.customers().create(
params, RequestOptions.builder().timeout(Duration.ofSeconds(30)).build()
Expand Down Expand Up @@ -367,6 +425,42 @@ OrbClient client = OrbOkHttpClient.builder()
.build();
```

### Custom HTTP client

The SDK consists of three artifacts:

- `orb-java-core`
- Contains core SDK logic
- Does not depend on [OkHttp](https://square.github.io/okhttp)
- Exposes [`OrbClient`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClient.kt), [`OrbClientAsync`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClientAsync.kt), [`OrbClientImpl`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClientImpl.kt), and [`OrbClientAsyncImpl`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClientAsyncImpl.kt), all of which can work with any HTTP client
- `orb-java-client-okhttp`
- Depends on [OkHttp](https://square.github.io/okhttp)
- Exposes [`OrbOkHttpClient`](orb-java-client-okhttp/src/main/kotlin/com/withorb/api/client/okhttp/OrbOkHttpClient.kt) and [`OrbOkHttpClientAsync`](orb-java-client-okhttp/src/main/kotlin/com/withorb/api/client/okhttp/OrbOkHttpClientAsync.kt), which provide a way to construct [`OrbClientImpl`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClientImpl.kt) and [`OrbClientAsyncImpl`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClientAsyncImpl.kt), respectively, using OkHttp
- `orb-java`
- Depends on and exposes the APIs of both `orb-java-core` and `orb-java-client-okhttp`
- Does not have its own logic

This structure allows replacing the SDK's default HTTP client without pulling in unnecessary dependencies.

#### Customized [`OkHttpClient`](https://square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.html)

> [!TIP]
> Try the available [network options](#network-options) before replacing the default client.

To use a customized `OkHttpClient`:

1. Replace your [`orb-java` dependency](#installation) with `orb-java-core`
2. Copy `orb-java-client-okhttp`'s [`OkHttpClient`](orb-java-client-okhttp/src/main/kotlin/com/withorb/api/client/okhttp/OkHttpClient.kt) class into your code and customize it
3. Construct [`OrbClientImpl`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClientImpl.kt) or [`OrbClientAsyncImpl`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClientAsyncImpl.kt), similarly to [`OrbOkHttpClient`](orb-java-client-okhttp/src/main/kotlin/com/withorb/api/client/okhttp/OrbOkHttpClient.kt) or [`OrbOkHttpClientAsync`](orb-java-client-okhttp/src/main/kotlin/com/withorb/api/client/okhttp/OrbOkHttpClientAsync.kt), using your customized client

### Completely custom HTTP client

To use a completely custom HTTP client:

1. Replace your [`orb-java` dependency](#installation) with `orb-java-core`
2. Write a class that implements the [`HttpClient`](orb-java-core/src/main/kotlin/com/withorb/api/core/http/HttpClient.kt) interface
3. Construct [`OrbClientImpl`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClientImpl.kt) or [`OrbClientAsyncImpl`](orb-java-core/src/main/kotlin/com/withorb/api/client/OrbClientAsyncImpl.kt), similarly to [`OrbOkHttpClient`](orb-java-client-okhttp/src/main/kotlin/com/withorb/api/client/okhttp/OrbOkHttpClient.kt) or [`OrbOkHttpClientAsync`](orb-java-client-okhttp/src/main/kotlin/com/withorb/api/client/okhttp/OrbOkHttpClientAsync.kt), using your new client class

## Undocumented API functionality

The SDK is typed for convenient usage of the documented API. However, it also supports working with undocumented or not yet supported parts of the API.
Expand Down Expand Up @@ -540,7 +634,6 @@ Or configure the method call to validate the response using the `responseValidat

```java
import com.withorb.api.models.Customer;
import com.withorb.api.models.CustomerCreateParams;

Customer customer = client.customers().create(
params, RequestOptions.builder().responseValidation(true).build()
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ before making any information public.
## Reporting Non-SDK Related Security Issues

If you encounter security issues that are not directly related to SDKs but pertain to the services
or products provided by Orb please follow the respective company's security reporting guidelines.
or products provided by Orb, please follow the respective company's security reporting guidelines.

### Orb Terms and Policies

Please contact [email protected] for any questions or concerns regarding security of our services.
Please contact [email protected] for any questions or concerns regarding the security of our services.

---

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
allprojects {
group = "com.withorb.api"
version = "0.56.0" // x-release-please-version
version = "0.57.0" // x-release-please-version
}
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/orb.java.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ configure<SpotlessExtension> {

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
languageVersion.set(JavaLanguageVersion.of(21))
}

sourceCompatibility = JavaVersion.VERSION_1_8
Expand Down
Loading
Loading