Skip to content

Releases: restatedev/sdk-java

2.0.0

10 Apr 12:51
e254573
Compare
Choose a tag to compare

Java/Kotlin SDK 2.0

We're pleased to announce the release of Java/Kotlin SDK 2.0, in combination with Restate 1.3.
Check out the announcement blog post for more details about Restate 1.3 and the new SDK features: https://restate.dev/blog/announcing-restate-1.3/

Below are the changes specific to the Java/Kotlin SDK.

What's new and what changed

New meta packages

From now on you don't need to pick individual packages of the SDK to get started, but you can use the new meta packages:

  • dev.restate:sdk-java-http for Java API + HTTP endpoint (example build.gradle.kts/pom.xml)
  • dev.restate:sdk-java-lambda for Java API + Lambda endpoint
  • dev.restate:sdk-kotlin-http for Kotlin API + HTTP endpoint (example build.gradle.kts)
  • dev.restate:sdk-kotlin-lambda for Kotlin API + Lambda endpoint

E.g. for Java (gradle):

annotationProcessor("dev.restate:sdk-api-gen:2.0.0")

// Java API + HTTP endpoint
implementation("dev.restate:sdk-java-http:2.0.0")

For kotlin:

// Code generator
ksp("dev.restate:sdk-api-kotlin-gen:2.0.0")

// Kotlin API + HTTP endpoint
implementation("dev.restate:sdk-kotlin-http:2.0.0")

You still need to individually import the code generator packages, as before, because those are not required at runtime.

Code generation and sharing code-generated artifacts

We made few changes to the generated code, with the goal of simplifying sharing code generated artifacts with 3rd party consumers of your Restate services.

Among the notable breaking changes:

  • All methods in generated clients, both for normal client and Context client, have an overload/optional parameter that allows to set additional options, including headers and idempotencyKey to use. Removed the old overloads accepting CallRequestOptions. For example this code:
client.handler("input", CallRequestOptions.DEFAULT.withIdempotency("my key"))

becomes

client.handler("input", opts -> opts.idempotencyKey("my key"))
  • Annotations @Service/@VirtualObject/@Workflow name argument is deprecated, you can now override the name used by Restate for both services and handlers using the @Name annotation. This name won't affect anymore the name prefix of the generated classes.
  • The clients method .send(Duration) has been removed in favor of overloads/optional parameter to perform one way calls with delay.
  • The new class [your service name]Handlers contains inside the old class [your service name]Metadata.
  • All send methods in context clients now return InvocationHandle.

A new class will now be generated, called [your service name]Handlers, that lets you easily call your service as follows:

// For service to service
GreeterHandlers.greet(request).call(ctx)
GreeterHandlers.greet(request).send(ctx)

// For Client
val restateClient: Client = Client.connect("https://my-restate/")
GreeterHandlers.greet(request).call(restateClient)
GreeterHandlers.greet(request).send(restateClient)

This class has few dependencies on some core classes of the SDK, that we commit to maintain ABI stable.
You can publish/share this generated class, and use it in combination with the Client simply importing the module dev.restate:client for Java or dev.restate:client-kotlin for Kotlin.

On top of that, this class works both for Kotlin API users and with Java API users, letting you call from Java to Kotlin and vice versa.

If you don't use the [...]Client class, but you use only the [...]Handlers, we suggest disabling its code generation as follows. For Java (gradle):

tasks {
  withType<JavaCompile> {
    options.compilerArgs.addAll(
      listOf(
        "-Adev.restate.codegen.disabledClientGeneration=my.fqcn.ServiceName"
      )
    )
  }
}

In Kotlin KSP (gradle):

ksp {
  arg("dev.restate.codegen.disabledClientGeneration", "my.fqcn.ServiceName")
}

Note: the generated artifacts from the SDK 1.x versions ARE NOT compatible with the generated artifacts from 2.x onward.
From SDK 2.x, we commit to a stable ABI between generated code artifacts and the SDK versions, meaning you'll be able to safely mix code generated artifacts with SDK version. For example, you'll be able to import a code generated artifact using SDK 2.0 in a project using SDK 2.1.

Client changes

We overhauled the client to interact with Restate. Now it lives in a new maven module ad hoc called dev.restate:client, which you can import separately from the rest of the SDK when you need to interact only with Restate from another Java/Kotlin application.

Notable changes:

  • Renamed package dev.restate.sdk.client to dev.restate.client
  • Renamed dev.restate.sdk.client.CallRequestOptions to dev.restate.client.RequestOptions
  • Now all client methods returns headers and status code, see interface dev.restate.client.ResponseHead.
  • It is possible to bootstrap your own Client implementation using the HTTP client of your choice extending dev.restate.client.base.BaseClient

Endpoint and RestateHttpServer

We now expose a uniform API across Http and Lambda support to build your service endpoint. In Java:

var endpoint = Endpoint
        .bind(new Greeter())
        // Run Counter on virtual threads
        .bind(new Counter(), HandlerRunner.Options.withExecutor(Executors.newVirtualThreadPerTaskExecutor()));

// E.g. bind to server
RestateHttpServer.listen(endpoint);

In Kotlin:

val endpoint = endpoint {
  bind(Greeter())
  // Decorate the coroutine context used by the handler
  bind(Counter(), HandlerRunner.Options(Dispatchers.Default + CoroutineName("counter")))
}

// E.g. bind to server
RestateHttpServer.listen(endpoint)

Using HttpEndpointRequestHandler.fromEndpoint(Endpoint) it is also possible to get a Vert.x request handler for your endpoint, that can be used to build the HTTP server manually.

Notable changes:

  • RestateHttpEndpointBuilder was deprecated, use RestateHttpServer instead.
  • RestateLambdaEndpointBuilder was removed, now BaseRestateLambdaHandler.register takes Endpoint.Builder as argument.

The DurableFuture interface

We renamed the Awaitable to DurableFuture and reworked few of its methods, to make it easier to interact with asynchronous events and compose them:

  • Added DurableFuture.withTimeout(Duration) to return a future composed with the timeout. This has the same behavior as DurableFuture.await(Duration) but it returns a future that can be later awaited, instead of awaiting the future immediately.
  • DurableFuture.await(Duration) now throws dev.restate.sdk.common.TimeoutException instead of java.util.concurrent.TimeoutException.
  • Added DurableFuture.map(successMapper), DurableFuture.map(successMapper, failureMapper) and DurableFuture.mapFailure(failureMapper), to map futures result once completed.

Check out the respective DurableFuture Javadocs/DurableFuture KotlinDocs for more details.

Deterministic resilient concurrency

As described in the blog post, Restate 1.3 improves support over deterministic concurrency.

In Java we expose the new API Select to await on multiple futures at the same time:

DurableFuture<String> a12 = Select.<String>select()
        .or(a1)
        .or(a2);

In Kotlin you can use the select function, which now returns a DurableFuture itself and can be composed too:

select {
  a1.onAwait { it }
  a2.onAwait { it }
}

ctx.runAsync to compose asynchronous side effects

Both in Java and Kotlin you can now use the ctx.runAsync API in order to execute a side effect, and return a DurableFuture instead than the result immediately. You can then compose this future with other DurableFutures, for example to implement fan-in/fan-out operations.

InvocationHandle for finer control over service-to-service communication

As described in the blog post, Restate 1.3 features new APIs to interact with running invocations.

All these features are encapsulated in the new InvocationHandle(Javadocs/Kotlin docs) API:

val handle = GreeterClient.fromContext(context).send().greet(request)

// Get invocation id
val invocationId = handle.invocationId()

// Cancel invocation
handle.cancel()

// Attach and await result
val result = handle.attach().await()

New Serde stack

We overhauled the Serde stack completely. Now you don't need to pass around, neither figure out Serdes anymore, but you just need to focus on what types you need. For example:

// Defining a state key
StateKey<Integer> REMINDER_COUNT = StateKey.of("reminder_count", Integer.TYPE);

// Using ctx.run
String result = ctx.run(String.class, () -> doSideEffect());

Or for generic types:

List<SubTask> subTasks = ctx.r...
Read more

v1.2.0: Spring Boot and revamped testing tools

20 Nov 10:22
17acfc4
Compare
Choose a tag to compare

We're pleased to announce the release of the Java SDK 1.2.0

New features

Notable changes

  • The ctx.run with RetryPolicy has been promoted to stable feature, check the Javadocs for more details.
  • You can now use checked exceptions within your @Handler annotated methods.

Breaking changes

  • Bumped minimum JDK version to 17
  • Because of a breaking change within log4j, you MUST either bump log4j-core to >= 2.24, or exclude the log4j-api dependency when depending on the SDK. For example, in gradle:
// Restate SDK
implementation("dev.restate:sdk-api:$restateVersion") {
   // Exclude transitive deps on log4j2
  exclude(group = "org.apache.logging.log4j")
}
implementation("dev.restate:sdk-http-vertx:$restateVersion") {
  exclude(group = "org.apache.logging.log4j")
}
// To use Jackson to read/write state entries (optional)
implementation("dev.restate:sdk-serde-jackson:$restateVersion") {
  exclude(group = "org.apache.logging.log4j")
}

// Pin log4j2 to 2.20
implementation("org.apache.logging.log4j:log4j-core:2.20.0")
implementation("org.apache.logging.log4j:log4j-api:2.20.0") 
  • This release is not bytecode compatible with previous releases, meaning you can't mix the annotation processor generated code from SDK <= 1.2.0 with this release.
  • This release is compatible with Restate >= 1.1

Changelog

Full Changelog: v1.1.1...v1.2.0

1.1.1

16 Oct 14:18
d479a46
Compare
Choose a tag to compare

What's Changed

Full Changelog: v1.1.0...v1.1.1

1.1.0

09 Sep 15:23
Compare
Choose a tag to compare

New features

  • [Preview] Add retry policies for run operations, to limit the amount of retries/the duration of the retries
  • The ingress client now supports the ability to retrieve invocations/attach to existing invocations using idempotency id

What's Changed

Full Changelog: v1.0.0...v1.1.0

Restate 1.0

07 Jun 08:04
fd335fb
Compare
Choose a tag to compare

We're happy to announce that Restate has reached the 1.0 milestone!

Check the Restate 1.0 release for more details.

Workflow API

We have introduced a new API to simplify building workflows, check out the documentation: https://docs.restate.dev/develop/java/workflows

Breaking changes from 0.9

  • Split CoreSerdes in JsonSerdes for the json primitive types and move RAW, BYTE_BUFFER AND VOID into the Serde interface by @slinkydeveloper in #330
  • Remove protobuf from the public api of sdk-common by @slinkydeveloper in #321
  • Rename the ingress client and the connect method by @slinkydeveloper in #336

Other changes

Full Changelog: v0.9.2...v1.0.0

0.9.2

03 May 08:21
61cef6e
Compare
Choose a tag to compare

What's Changed

  • [Release] Bump to 0.10.0-SNAPSHOT by @github-actions in #306
  • Raw handlers by @slinkydeveloper in #303
  • [Release] Bump to 0.9.2 by @github-actions in #307

Full Changelog: v0.9.1...v0.9.2

0.9.1

30 Apr 09:12
c426b41
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.9.0...v0.9.1

v0.9.0: New DevEx

25 Apr 09:10
Compare
Choose a tag to compare

This release features a completely overhauled development experience. We suggest checking out the new documentation https://docs.restate.dev/develop/java/overview for more details and the new examples https://github.com/restatedev/examples.

What's Changed

Full Changelog: v0.8.0...v0.9.0

v0.8.0

01 Mar 09:36
0407700
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v0.7.0...v0.8.0

v0.7.0

01 Feb 14:31
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.6.0...v0.7.0