Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

- Add the typed Functions API client, execution and deployment operations, and examples.

## 2.0.0

- Establish the initial SDK release with the multi-module build, shared transport, typed failures, pagination, polling, and SSE support.
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ The configured request timeout applies to each ordinary call attempt and `stream


Browse the [service API reference](./docs/api/README.md) for all named operations and route signatures.
Functions endpoints are not in the current OpenAPI snapshot; see the [Functions API guide](./docs/api/functions.md) for its typed client and example.

## Build and verify

Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/dev/frontal/sdk/api/ApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
}

/** Executes an endpoint and returns the successful status, headers, and raw response bytes. */
public ApiResponse execute(Endpoint endpoint, List<String> pathParams, QueryParams query, @Nullable JsonNode body)

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @throws for java.lang.InterruptedException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @throws for java.io.IOException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for body

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for query

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for pathParams

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for endpoint

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @throws for java.lang.InterruptedException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @throws for java.io.IOException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for body

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for query

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for pathParams

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for endpoint

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @throws for java.lang.InterruptedException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @throws for java.io.IOException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for body

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for query

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for pathParams

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for endpoint

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @throws for java.lang.InterruptedException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @throws for java.io.IOException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for body

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for query

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for pathParams

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for endpoint

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @throws for java.lang.InterruptedException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @throws for java.io.IOException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for body

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for query

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for pathParams

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for endpoint

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @throws for java.lang.InterruptedException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @throws for java.io.IOException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for body

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for query

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for pathParams

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for endpoint

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @throws for java.lang.InterruptedException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @throws for java.io.IOException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for body

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for query

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for pathParams

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for endpoint

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @throws for java.lang.InterruptedException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @throws for java.io.IOException

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for body

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for query

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for pathParams

Check warning on line 109 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for endpoint
throws IOException, InterruptedException {
Objects.requireNonNull(endpoint, "endpoint");
if (endpoint.method() == HttpMethod.STREAM
Expand All @@ -123,7 +123,7 @@
}

/** Sends a request and returns its body as bytes. */
public byte[] requestBytes(Endpoint endpoint, List<String> pathParams, QueryParams query, @Nullable JsonNode body)

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for query

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for pathParams

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for endpoint

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for query

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for pathParams

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for endpoint

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for query

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for pathParams

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 17

no @PARAM for endpoint

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for query

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for pathParams

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / macos-latest / Java 21

no @PARAM for endpoint

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for query

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for pathParams

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for endpoint

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for query

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for pathParams

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for endpoint

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for query

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for pathParams

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 21

no @PARAM for endpoint

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for query

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for pathParams

Check warning on line 126 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View workflow job for this annotation

GitHub Actions / CI / ubuntu-latest / Java 17

no @PARAM for endpoint
throws IOException, InterruptedException {
return execute(endpoint, pathParams, query, body).body();
}
Expand Down Expand Up @@ -167,7 +167,7 @@
}

/** Opens a successful response body without buffering it. The caller must close the result. */
public ApiStream streamBody(Endpoint endpoint, List<String> pathParams, QueryParams query, @Nullable JsonNode body)

Check failure on line 170 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 20 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=frontal-labs_sdk-java&issues=AaEhR3SOcV8G6tai3A1f&open=AaEhR3SOcV8G6tai3A1f&pullRequest=15
throws IOException, InterruptedException {
Objects.requireNonNull(endpoint, "endpoint");
if (endpoint.method() == HttpMethod.STREAM
Expand All @@ -178,7 +178,7 @@
String requestId = UUID.randomUUID().toString();
RequestBody requestBody = requestBody(endpoint.method(), body);
String contentType = contentType(body);
int attempts = endpoint.method().wireMethod().equals("GET") ? config.maxRetries() + 1 : 1;
int attempts = endpoint.method().wireMethod().equals("GET") ? config.maxRetriesFor(endpoint.service()) + 1 : 1;
for (int attempt = 0; attempt < attempts; attempt++) {
Request request = buildRequest(endpoint, pathParams, query, requestBody, contentType, "*/*", requestId);
Response response;
Expand Down Expand Up @@ -360,7 +360,7 @@
return new SseEventIterator(streamResponse(endpoint, pathParams, query));
}

private ApiResponse exchange(

Check failure on line 363 in core/src/main/java/dev/frontal/sdk/api/ApiClient.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 22 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=frontal-labs_sdk-java&issues=AaEhR3SOcV8G6tai3A1g&open=AaEhR3SOcV8G6tai3A1g&pullRequest=15
Endpoint endpoint,
List<String> pathParams,
QueryParams query,
Expand All @@ -369,7 +369,7 @@
String accept)
throws IOException, InterruptedException {
String requestId = UUID.randomUUID().toString();
int attempts = endpoint.method().wireMethod().equals("GET") ? config.maxRetries() + 1 : 1;
int attempts = endpoint.method().wireMethod().equals("GET") ? config.maxRetriesFor(endpoint.service()) + 1 : 1;
for (int attempt = 0; attempt < attempts; attempt++) {
Request request = buildRequest(endpoint, pathParams, query, requestBody, contentType, accept, requestId);
Response response;
Expand Down
16 changes: 15 additions & 1 deletion core/src/main/java/dev/frontal/sdk/config/ClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@
public final class ClientConfig {
public static final URI DEFAULT_API_BASE_URL = URI.create("https://api.frontal.dev/v1");
public static final URI DEFAULT_AI_BASE_URL = URI.create("https://ai.frontal.dev");
private static final int DEFAULT_MAX_RETRIES = 2;
private static final int DEFAULT_FUNCTIONS_MAX_RETRIES = 3;

private final @Nullable String apiKey;
private final URI apiBaseUrl;
private final URI aiBaseUrl;
private final Duration connectTimeout;
private final Duration requestTimeout;
private final int maxRetries;
private final boolean maxRetriesExplicit;
private final long maxResponseBytes;
private final int maxErrorBodyBytes;
private final String userAgent;
Expand All @@ -42,6 +45,7 @@ private ClientConfig(Builder builder) {
throw new IllegalArgumentException("maxErrorBodyBytes must be positive");
}
maxRetries = builder.maxRetries;
maxRetriesExplicit = builder.maxRetriesExplicit;
maxResponseBytes = builder.maxResponseBytes;
maxErrorBodyBytes = builder.maxErrorBodyBytes;
userAgent = requireText(builder.userAgent, "userAgent");
Expand Down Expand Up @@ -131,6 +135,14 @@ public int maxRetries() {
return maxRetries;
}

int maxRetriesFor(ApiService service) {
Objects.requireNonNull(service, "service");
if (!maxRetriesExplicit && service == ApiService.FUNCTIONS) {
return DEFAULT_FUNCTIONS_MAX_RETRIES;
}
return maxRetries;
}

public long maxResponseBytes() {
return maxResponseBytes;
}
Expand Down Expand Up @@ -213,7 +225,8 @@ public static final class Builder {
private URI aiBaseUrl = DEFAULT_AI_BASE_URL;
private Duration connectTimeout = Duration.ofSeconds(10);
private Duration requestTimeout = Duration.ofSeconds(30);
private int maxRetries = 2;
private int maxRetries = DEFAULT_MAX_RETRIES;
private boolean maxRetriesExplicit;
private long maxResponseBytes = 64L * 1024 * 1024;
private int maxErrorBodyBytes = 16 * 1024;
private String userAgent = "frontal-java-sdk/2.0.0";
Expand Down Expand Up @@ -259,6 +272,7 @@ public Builder requestTimeout(Duration requestTimeout) {

public Builder maxRetries(int maxRetries) {
this.maxRetries = maxRetries;
this.maxRetriesExplicit = true;
return this;
}

Expand Down
1 change: 1 addition & 0 deletions core/src/main/java/dev/frontal/sdk/models/ApiService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public enum ApiService {
WORKFLOWS("workflows"),
CONNECTION_TESTS("connection-tests"),
EVENTS("events"),
FUNCTIONS("functions"),
INVOCATIONS("invocations"),
PROVIDERS("providers"),
WEBHOOK_ENDPOINTS("webhook-endpoints");
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Java documentation

Read `OVERVIEW.md` for the SDK surface, `ARCHITECTURE.md` for the module and request flow, and `ONBOARDING.md` to set up the toolchain. Browse [the service API reference](./api/README.md) for the generated operation catalog. See the root README for pagination, error handling, streaming, and serialization examples. Use `TESTING.md` for verification and `PUBLISHING.md` for release steps.
Read `OVERVIEW.md` for the SDK surface, `ARCHITECTURE.md` for the module and request flow, and `ONBOARDING.md` to set up the toolchain. Browse [the service API reference](./api/README.md) for the generated operation catalog and the [Functions API guide](./api/functions.md) for the Functions routes, which are not in the current contract snapshot. See the root README for pagination, error handling, streaming, and serialization examples. Use `TESTING.md` for verification and `PUBLISHING.md` for release steps.
27 changes: 1 addition & 26 deletions docs/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,4 @@

Generated from the committed route catalog for SDK service clients.

Call-shaped listing of every operation: [methods as code](./methods-as-code.md).

| Service | Routes | Reference |
| --- | ---: | --- |
| agents | 14 | [agents](./agents.md) |
| ai | 9 | [ai](./ai.md) |
| audit | 4 | [audit](./audit.md) |
| auth | 66 | [auth](./auth.md) |
| billing | 23 | [billing](./billing.md) |
| blob | 8 | [blob](./blob.md) |
| connection-tests | 1 | [connection-tests](./connection-tests.md) |
| connectors | 12 | [connectors](./connectors.md) |
| data | 151 | [data](./data.md) |
| events | 17 | [events](./events.md) |
| governance | 24 | [governance](./governance.md) |
| invocations | 1 | [invocations](./invocations.md) |
| lineage | 7 | [lineage](./lineage.md) |
| observability | 31 | [observability](./observability.md) |
| ontology | 171 | [ontology](./ontology.md) |
| pipelines | 11 | [pipelines](./pipelines.md) |
| providers | 1 | [providers](./providers.md) |
| react | 0 | [react](./react.md) |
| schedules | 10 | [schedules](./schedules.md) |
| webhook-endpoints | 7 | [webhook-endpoints](./webhook-endpoints.md) |
| webhooks | 10 | [webhooks](./webhooks.md) |
| workflows | 30 | [workflows](./workflows.md) |
The Functions endpoints currently come from the TypeScript SDK because they are not in the committed contract inventory. See the [Functions API guide](./functions.md) for their Java client methods and models.
60 changes: 60 additions & 0 deletions docs/api/functions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Functions API

The Java Functions client follows the operation and payload shapes in the [TypeScript Functions package](https://github.com/frontal-labs/sdk-typescript/blob/master/packages/functions/src/namespace.ts). These routes are not present in the checked-in OpenAPI snapshots or `contracts/sdk-endpoints.json` yet, so Functions uses the shared Java transport with a local route catalog.

## Client and configuration

Use `Frontal.functions()` to access this API. It shares the configured bearer API key, API base URL, timeout, retry behavior, environment header, and Jackson mapper with the rest of the SDK.

```java
try (Frontal frontal = Frontal.builder()
.apiKey(System.getenv("FRONTAL_API_KEY"))
.apiBaseUrl("https://api.frontal.dev/v1")
.requestTimeout(Duration.ofSeconds(30))
.maxRetries(3)
.build()) {
FunctionDefinition definition = FunctionDefinition.builder("hello")
.runtime(FunctionRuntime.NODEJS22)
.entrypoint("index.handler")
.build();
FunctionResource function = frontal.functions().create(definition);
FunctionInvocationResult result = frontal.functions()
.executions()
.invoke(new FunctionInvocationInput(function.id()));
}
```

The default API URL is `https://api.frontal.dev/v1`, request timeout is 30 seconds, and Functions GET requests retry up to three times by default, matching the TypeScript package. Setting `maxRetries` on the builder explicitly overrides the retry count for Functions and other services. Other Java services retain the shared default of two retries.

## Operations

| Java call | HTTP operation |
| --- | --- |
| `functions.create(definition)` | `POST /functions` |
| `functions.list(query)` | `GET /functions?cursor=&limit=` |
| `functions.get(functionId)` | `GET /functions/{functionId}` |
| `functions.update(functionId, definition)` | `PATCH /functions/{functionId}` |
| `functions.delete(functionId)` | `DELETE /functions/{functionId}` |
| `functions.versions().list(functionId, query)` | `GET /functions/{functionId}/versions?cursor=&limit=` |
| `functions.versions().get(functionId, version)` | `GET /functions/{functionId}/versions/{version}` |
| `functions.versions().publish(functionId, version)` | `POST /functions/{functionId}/versions/{version}/publish` |
| `functions.deployments().deploy(functionId, version)` | `POST /functions/{functionId}/versions/{version}/deploy` |
| `functions.deployments().status(functionId, version)` | `GET /functions/{functionId}/versions/{version}/deployment/status` |
| `functions.executions().invoke(input)` | `POST /functions/invoke` |
| `functions.executions().invokeAsync(input)` | `POST /functions/invoke-async` |
| `functions.executions().getExecution(executionId)` | `GET /functions/executions/{executionId}` |
| `functions.executions().getResult(executionId)` | `GET /functions/executions/{executionId}/result` |
| `functions.executions().listExecutions(query)` | `GET /functions/executions?cursor=&limit=&functionId=&status=` |
| `functions.executions().cancelExecution(executionId)` | `POST /functions/executions/{executionId}/cancel` |

List query values are provided with `QueryParams.builder()`. IDs are encoded as individual URL path segments. Service calls are synchronous and report transport/API failures through the SDK's `IOException` hierarchy.

## Models and JSON values

`FunctionDefinition` requires `name`, `runtime`, and `entrypoint`. Its builder accepts optional `description`, `source`, `inputSchema`, `outputSchema`, `dependencies`, `envVars`, `secrets`, `memory` (MB), `timeout` (seconds), and `permissions` (`ontology` and `actions` string lists). Runtime values are `NODEJS20`, `NODEJS22`, and `PYTHON311`; their JSON forms are `nodejs20`, `nodejs22`, and `python311`.

Schemas and invocation inputs/results use Jackson `JsonNode`, so nested object keys and arbitrary JSON values remain under caller control. Resource statuses use `FunctionStatus` (`DRAFT`, `ACTIVE`, `DEPRECATED`, `FAILED`) with the corresponding lowercase wire values. List models expose their `functions`, `versions`, or `executions` collection and `FunctionPagination` metadata.

## Runnable example

See [`FunctionsQuickstartTest`](../../examples/src/test/java/dev/frontal/examples/FunctionsQuickstartTest.java) for an executable example that constructs a configured client, defines a function, and invokes it against MockWebServer.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package dev.frontal.examples;

import static org.junit.jupiter.api.Assertions.assertEquals;

import com.fasterxml.jackson.databind.JsonNode;
import dev.frontal.sdk.Frontal;
import dev.frontal.sdk.FunctionDefinition;
import dev.frontal.sdk.FunctionInvocationInput;
import dev.frontal.sdk.FunctionPermission;
import dev.frontal.sdk.FunctionRuntime;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.Test;

class FunctionsQuickstartTest {
@Test
void definesAndInvokesAFunctionWithThePublicClient() throws Exception {
try (MockWebServer mock = new MockWebServer()) {
mock.start();
mock.enqueue(new MockResponse()
.setBody("{\"id\":\"fn_123\",\"name\":\"hello\","
+ "\"runtime\":\"nodejs22\",\"entrypoint\":\"index.handler\","
+ "\"status\":\"active\",\"version\":1,\"createdAt\":\"2026-10-09T10:00:00Z\","
+ "\"updatedAt\":\"2026-10-09T10:00:00Z\"}"));
mock.enqueue(new MockResponse()
.setBody("{\"executionId\":\"exec_123\",\"result\":{\"message\":\"hello, Ada\"}}"));

try (Frontal frontal = Frontal.builder()
.apiKey(System.getenv().getOrDefault("FRONTAL_API_KEY", "frt_example_key"))
.apiBaseUrl(mock.url("/v1").toString())
.requestTimeout(Duration.ofSeconds(5))
.maxRetries(0)
.build()) {
FunctionDefinition definition = FunctionDefinition.builder("hello")
.description("Greets a person")
.runtime(FunctionRuntime.NODEJS22)
.entrypoint("index.handler")
.source("blob://functions/hello")
.dependencies(List.of("zod"))
.envVars(Map.of("GREETING", "hello"))
.permissions(new FunctionPermission(List.of(), List.of("read:name")))
.build();
var created = frontal.functions().create(definition);
JsonNode input =
frontal.apiClient().objectMapper().createObjectNode().put("name", "Ada");
var invocation =
frontal.functions().executions().invoke(new FunctionInvocationInput(created.id(), input));

assertEquals("fn_123", created.id());
assertEquals("hello, Ada", invocation.result().path("message").asText());
}
}
}
}
6 changes: 6 additions & 0 deletions sdk/src/main/java/dev/frontal/sdk/api/Frontal.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import org.jspecify.annotations.Nullable;

/** Root client. Every service accessor shares one configured transport. */
public final class Frontal implements AutoCloseable {

Check warning on line 12 in sdk/src/main/java/dev/frontal/sdk/api/Frontal.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Split this “Monster Class” into smaller and more specialized ones to reduce its dependencies on other classes from 30 to the maximum authorized 20 or less.

See more on https://sonarcloud.io/project/issues?id=frontal-labs_sdk-java&issues=AaEhR3SBcV8G6tai3A1e&open=AaEhR3SBcV8G6tai3A1e&pullRequest=15
private final ApiClient apiClient;
private final Map<ApiService, ServiceClient> services;

Expand Down Expand Up @@ -43,6 +43,7 @@
case CONNECTION_TESTS -> new ConnectionTestsClient(apiClient);
case DATA -> new DataClient(apiClient);
case EVENTS -> new EventsClient(apiClient);
case FUNCTIONS -> new FunctionsClient(apiClient);
case GOVERNANCE -> new GovernanceClient(apiClient);
case INVOCATIONS -> new InvocationsClient(apiClient);
case LINEAGE -> new LineageClient(apiClient);
Expand Down Expand Up @@ -120,6 +121,11 @@
return (EventsClient) service(ApiService.EVENTS);
}

/** Returns the Functions API client. */
public FunctionsClient functions() {
return (FunctionsClient) service(ApiService.FUNCTIONS);
}

public GovernanceClient governance() {
return (GovernanceClient) service(ApiService.GOVERNANCE);
}
Expand Down
Loading
Loading