Skip to content

Commit cbc928e

Browse files
committed
feat: add example
1 parent aff7424 commit cbc928e

9 files changed

Lines changed: 624 additions & 0 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# OpenFGA Configuration (REQUIRED)
2+
FGA_API_URL=http://localhost:8000
3+
FGA_STORE_ID=store_id_here
4+
FGA_MODEL_ID=model_id_here
5+
6+
# Authentication (optional - for authenticated OpenFGA instances)
7+
FGA_CLIENT_ID=client_id_here
8+
FGA_CLIENT_SECRET=client_secret_here
9+
FGA_API_AUDIENCE=api_audience_here
10+
FGA_API_TOKEN_ISSUER=api_issuer_here
11+
12+
# OpenTelemetry Configuration (for manual configuration mode - ./gradlew run)
13+
# These are used when running with manual OpenTelemetry setup
14+
# Note: When using the Java agent (./gradlew runWithAgent),
15+
# these values are overridden by the JVM arguments in build.gradle
16+
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
17+
OTEL_SERVICE_NAME=openfga-java-sdk-example
18+
OTEL_SERVICE_VERSION=1.0.0
19+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
all: build
2+
3+
openfga_version=latest
4+
5+
build:
6+
./gradlew build
7+
8+
run:
9+
./gradlew run
10+
11+
run-openfga:
12+
docker pull docker.io/openfga/openfga:${openfga_version} && \
13+
docker run -p 8080:8080 docker.io/openfga/openfga:${openfga_version} run
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Streamed List Objects Example
2+
3+
This example demonstrates how to use the Streamed ListObjects API in the OpenFGA Java SDK.
4+
5+
## What is Streamed ListObjects?
6+
7+
The StreamedListObjects API is similar to the regular ListObjects API, but with key differences:
8+
9+
1. **Streaming Response**: Instead of collecting all objects before returning a response, it streams them to the client as they are collected
10+
2. **No Result Limit**: The number of results returned is only limited by the execution timeout specified in the server configuration (`OPENFGA_LIST_OBJECTS_DEADLINE`)
11+
3. **Immediate Processing**: You can start processing results as they arrive, without waiting for the entire result set
12+
13+
## When to Use Streamed ListObjects
14+
15+
Use the Streamed ListObjects API when:
16+
17+
- You expect a large number of results that would take a long time to collect
18+
- You want to start processing results immediately rather than waiting for the complete set
19+
- You might not need all results (e.g., you want to stop after finding a certain number)
20+
- You want to avoid timeout issues with very large result sets
21+
22+
## Running the Example
23+
24+
### Prerequisites
25+
26+
- A running OpenFGA server (or use the [OpenFGA Playground](https://play.fga.dev/))
27+
28+
### Environment Variables
29+
30+
Set the following environment variables:
31+
32+
```bash
33+
# Required
34+
export FGA_API_URL=http://localhost:8080 # Your OpenFGA server URL
35+
36+
# Optional - for authenticated servers
37+
export FGA_CLIENT_ID=your_client_id
38+
export FGA_CLIENT_SECRET=your_client_secret
39+
export FGA_API_TOKEN_ISSUER=your_token_issuer
40+
export FGA_API_AUDIENCE=your_audience
41+
```
42+
43+
### Running
44+
45+
```bash
46+
make run
47+
```
48+
49+
## Code Examples
50+
51+
### Basic Usage
52+
53+
```java
54+
// Create a request
55+
var request = new ClientListObjectsRequest()
56+
.type("document")
57+
.relation("owner")
58+
.user("user:anne");
59+
60+
// Call the streaming API
61+
var objectStream = fgaClient.streamedListObjects(request).get();
62+
63+
// Collect all results
64+
List<String> objects = objectStream
65+
.map(StreamedListObjectsResponse::getObject)
66+
.collect(Collectors.toList());
67+
```
68+
69+
### Early Termination
70+
71+
```java
72+
// Get only the first 10 results
73+
var objectStream = fgaClient.streamedListObjects(request).get();
74+
List<String> firstTen = objectStream
75+
.map(StreamedListObjectsResponse::getObject)
76+
.limit(10)
77+
.collect(Collectors.toList());
78+
```
79+
80+
### Process as You Go
81+
82+
```java
83+
// Process each object immediately as it arrives
84+
var objectStream = fgaClient.streamedListObjects(request).get();
85+
objectStream
86+
.map(StreamedListObjectsResponse::getObject)
87+
.forEach(obj -> {
88+
// Do something with each object
89+
System.out.println("Processing: " + obj);
90+
});
91+
```
92+
93+
### With Options
94+
95+
```java
96+
// Use options to specify consistency preference
97+
var options = new ClientListObjectsOptions()
98+
.consistency(ConsistencyPreference.HIGHER_CONSISTENCY)
99+
.authorizationModelId("01GXSXXXXXXXXXXXXXXXX");
100+
101+
var objectStream = fgaClient.streamedListObjects(request, options).get();
102+
```
103+
104+
## Comparison with Regular ListObjects
105+
106+
| Feature | ListObjects | Streamed ListObjects |
107+
|---------|-------------|---------------------|
108+
| Result Collection | Waits for all results | Streams results as computed |
109+
| Result Limit | Limited by server pagination | Limited only by execution timeout |
110+
| Processing | Must wait for complete response | Can process immediately |
111+
| Use Case | Small to medium result sets | Large result sets, immediate processing |
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
plugins {
2+
id 'application'
3+
id 'com.diffplug.spotless' version '8.0.0'
4+
}
5+
6+
application {
7+
mainClass = 'dev.openfga.sdk.example.streamedlistobjects.StreamedListObjectsExample'
8+
}
9+
10+
repositories {
11+
mavenCentral()
12+
}
13+
14+
ext {
15+
jacksonVersion = "2.20.0"
16+
}
17+
18+
dependencies {
19+
implementation("dev.openfga:openfga-sdk:0.9.2")
20+
21+
// Serialization
22+
implementation("com.fasterxml.jackson.core:jackson-core:$jacksonVersion")
23+
implementation("com.fasterxml.jackson.core:jackson-annotations:$jacksonVersion")
24+
implementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
25+
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jacksonVersion")
26+
implementation("org.openapitools:jackson-databind-nullable:0.2.7")
27+
}
28+
29+
// Use spotless plugin to automatically format code, remove unused import, etc
30+
// To apply changes directly to the file, run `gradlew spotlessApply`
31+
// Ref: https://github.com/diffplug/spotless/tree/main/plugin-gradle
32+
spotless {
33+
// comment out below to run spotless as part of the `check` task
34+
enforceCheck false
35+
format 'misc', {
36+
// define the files (e.g. '*.gradle', '*.md') to apply `misc` to
37+
target '.gitignore'
38+
// define the steps to apply to those files
39+
trimTrailingWhitespace()
40+
indentWithSpaces() // Takes an integer argument if you don't like 4
41+
endWithNewline()
42+
}
43+
java {
44+
palantirJavaFormat()
45+
removeUnusedImports()
46+
importOrder()
47+
}
48+
}
49+
50+
// Use spotless plugin to automatically format code, remove unused import, etc
51+
// To apply changes directly to the file, run `gradlew spotlessApply`
52+
// Ref: https://github.com/diffplug/spotless/tree/main/plugin-gradle
53+
tasks.register('fmt') {
54+
dependsOn 'spotlessApply'
55+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
language=java
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
4+
networkTimeout=10000
5+
validateDistributionUrl=true
6+
zipStoreBase=GRADLE_USER_HOME
7+
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)