Releases: restatedev/sdk-java
2.0.0
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 (examplebuild.gradle.kts
/pom.xml
)dev.restate:sdk-java-lambda
for Java API + Lambda endpointdev.restate:sdk-kotlin-http
for Kotlin API + HTTP endpoint (examplebuild.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 andidempotencyKey
to use. Removed the old overloads acceptingCallRequestOptions
. 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 withdelay
. - 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
todev.restate.client
- Renamed
dev.restate.sdk.client.CallRequestOptions
todev.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 extendingdev.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, useRestateHttpServer
instead.RestateLambdaEndpointBuilder
was removed, nowBaseRestateLambdaHandler.register
takesEndpoint.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 asDurableFuture.await(Duration)
but it returns a future that can be later awaited, instead of awaiting the future immediately. DurableFuture.await(Duration)
now throwsdev.restate.sdk.common.TimeoutException
instead ofjava.util.concurrent.TimeoutException
.- Added
DurableFuture.map(successMapper)
,DurableFuture.map(successMapper, failureMapper)
andDurableFuture.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 DurableFuture
s, 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 Serde
s 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...
v1.2.0: Spring Boot and revamped testing tools
We're pleased to announce the release of the Java SDK 1.2.0
New features
- We now have a new Spring Boot to easily use the Restate SDK within your Spring Boot application. For more details, check out the example: https://github.com/restatedev/examples/tree/main/templates/java-maven-spring-boot
- The
sdk-testing
package has been revamped to a more friendly and easier to use API, you can check it out here https://github.com/restatedev/examples/blob/9a9c7cf85c830f33a5f257db3ec986a09a1878b0/templates/java-gradle/src/test/java/my/example/GreeterTest.java. The old API is still available but it's now deprecated, and will be removed in subsequent releases.
Notable changes
- The
ctx.run
withRetryPolicy
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 thelog4j-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
- [Release] Bump to 1.2.0-SNAPSHOT by @github-actions in #383
- Enable RawHandler test by @slinkydeveloper in #385
- New test tool with new action by @slinkydeveloper in #387
- Improve testing tools Javadocs by @slinkydeveloper in #388
- Fix builds by @slinkydeveloper in #389
- Introduce Spring Boot starter by @slinkydeveloper in #393
- Spring boot improvements by @slinkydeveloper in #394
- Add Json Schema for Req/Res types by @slinkydeveloper in #395
- Add documentation and metadata fields to EndpointManifest by @slinkydeveloper in #397
- Add title for classes by @slinkydeveloper in #398
- Bump minimum JDK to 17 by @slinkydeveloper in #400
- Bump minimum protocol version to 2 by @slinkydeveloper in #401
- Fix case where we pass ServiceDefinition to the builder already by @slinkydeveloper in #402
- Simple Json Schemas for Kotlin by @slinkydeveloper in #403
- Allow checked exceptions in annotated services by @slinkydeveloper in #407
- Fix code generation warning by @slinkydeveloper in #408
- More dependency bumping by @slinkydeveloper in #409
- Fix bad source version in ServiceProcessor by @slinkydeveloper in #410
- Be lenient with ServiceLoader not able to load classes by @slinkydeveloper in #411
- Few little improvements to testing by @slinkydeveloper in #413
- [Release] Bump to 1.2.0 by @github-actions in #412
Full Changelog: v1.1.1...v1.2.0
1.1.1
What's Changed
- Add interpreter test code by @slinkydeveloper in #379
- Bump to 1.2.0-SNAPSHOT by @slinkydeveloper in #380
- Make sure we don't check the invoke time for one way calls by @slinkydeveloper in #381
- [Release] Bump to 1.1.1 by @github-actions in #382
Full Changelog: v1.1.0...v1.1.1
1.1.0
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
- [Release] Bump to 1.1.0-SNAPSHOT by @github-actions in #350
- Javadocs by @slinkydeveloper in #347
- Add javadocs test by @slinkydeveloper in #352
- buildAndListen now fails on port not available by @slinkydeveloper in #353
- Add support to retrieve invocations from idempotency key by @slinkydeveloper in #359
- Better error message when missing context parameter by @slinkydeveloper in #360
- Fix Serde nullability annotations by @slinkydeveloper in #361
- Sdk test tool by @slinkydeveloper in #362
- Bump sdk-test-suite to 1.4 by @slinkydeveloper in #363
- E2E actions for running in runtime by @slinkydeveloper in #364
- More info on ingress logs by @slinkydeveloper in #365
- Update sdk-test-suite to 1.5 by @slinkydeveloper in #366
- Fix usage of new ingress exception constructor by @slinkydeveloper in #367
- Add env vars by @slinkydeveloper in #368
- A couple of changes to allow override the test artifact output (which would otherwise conflict) by @slinkydeveloper in #369
- Remove the old e2e job by @slinkydeveloper in #370
- New upgrade test by @slinkydeveloper in #371
- Update test tool to 1.8, with new delayed calls test by @slinkydeveloper in #372
- Make sure private methods cannot be annotated by @slinkydeveloper in #377
- Don't try to handle
Error
by @slinkydeveloper in #376 - Implement run retry policy by @slinkydeveloper in #375
- [Release] Bump to 1.1.0 by @github-actions in #378
Full Changelog: v1.0.0...v1.1.0
Restate 1.0
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
- [Release] Bump to 0.10.0-SNAPSHOT by @github-actions in #308
- Update admin api by @slinkydeveloper in #313
- Update Openapi generator to newest version by @slinkydeveloper in #314
- Integrate Java SDK with new service protocol negotiation mechanism by @tillrohrmann in #318
- Fix double logging the end message by @slinkydeveloper in #319
- Remove protobuf from the public api of sdk-common by @slinkydeveloper in #321
- Fix submit disambiguation by @slinkydeveloper in #320
- Verify that there can't be two handlers with same name by @slinkydeveloper in #326
- Add WorkflowHandle by @slinkydeveloper in #329
- Fix nullability problem wrt return type of kotlin services by @slinkydeveloper in #331
- Add SendStatus by @slinkydeveloper in #332
- Java/Kotlin docs for the new workflow api by @slinkydeveloper in #333
- Now send acks on combinators by @slinkydeveloper in #334
- Consecutive GetState with empty by @slinkydeveloper in #335
- Max concurrent streams by @slinkydeveloper in #337
- Rename the ingress client and the connect method by @slinkydeveloper in #336
- [kotlin] Fix nested types input/output code generation by @slinkydeveloper in #273
- General dependency bump by @slinkydeveloper in #339
- Allow more than one key in request signing by @slinkydeveloper in #340
- Add Awaitable#all(List) and Awaitable#any(List) by @slinkydeveloper in #338
- A lot of small linter fixes by @slinkydeveloper in #341
- Fix getOutput return type by @slinkydeveloper in #342
- Fix GetOutput status code error handling -_-" by @slinkydeveloper in #343
- Move all the encoding/decoding of messages within sdk-core by @slinkydeveloper in #344
- Remove stream when initializing user state storage by @slinkydeveloper in #345
- minor doc fix by @AhmedSoliman in #346
- Adjust the README for 1.0 by @slinkydeveloper in #348
- [Release] Bump to 1.0.0 by @github-actions in #349
Full Changelog: v0.9.2...v1.0.0
0.9.2
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
What's Changed
- [Release] Bump to 0.10.0-SNAPSHOT by @github-actions in #301
- Update README by @slinkydeveloper in #271
- Update workflow deps by @tillrohrmann in #302
- Implement request identity by @slinkydeveloper in #297
- VOID should return null content type by @slinkydeveloper in #304
- [Release] Bump to 0.9.1 by @github-actions in #305
Full Changelog: v0.9.0...v0.9.1
v0.9.0: New DevEx
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
- [Release] Bump to 0.9.0-SNAPSHOT by @github-actions in #233
- New interface refactor by @slinkydeveloper in #236
- New interface refactor (sdk-api-kotlin) by @slinkydeveloper in #238
- sdk-api-kotlin-gen by @slinkydeveloper in #240
- Use simple class name as default name by @slinkydeveloper in #241
- Request headers and Executor injection changes. by @slinkydeveloper in #242
- Remove TerminalException.Code enum and replace it with just an integer. by @slinkydeveloper in #248
- Add RequestOptions to ingress requests by @slinkydeveloper in #250
- Move Protobuf serde to separate module by @slinkydeveloper in #253
- Make the ingress client async by @slinkydeveloper in #252
- Add resolve/reject awakeables from ingress by @slinkydeveloper in #254
- Fix bad request error code by @slinkydeveloper in #255
- Fix ingress awakeable resolve/reject by @slinkydeveloper in #256
- Fix broken links to the docs by @gvdongen in #257
- Adapt latest protocol changes by @slinkydeveloper in #258
- Correct content-type by @slinkydeveloper in #261
- Merge send methods and rename with in bind by @slinkydeveloper in #263
- Fix usage of IngressClient in code generated by kotlin gen by @slinkydeveloper in #264
- Fix logging context propagation by @slinkydeveloper in #270
- Rename ctx.sideEffect in ctx.run by @slinkydeveloper in #267
- Fix options injection in kt codegen by @slinkydeveloper in #274
- Remove idempotency retain period from ingress client options by @slinkydeveloper in #268
- Add support for Send delay in ingress client by @slinkydeveloper in #275
- More implicitness in kotlin by @slinkydeveloper in #277
- More logging on jackson ser/de by @slinkydeveloper in #279
- Fix corner cases around code generation and "reserved" keywords by @slinkydeveloper in #280
- Named side effects by @slinkydeveloper in #282
- Side effects changes by @slinkydeveloper in #284
- Add x-restate-server header in responses by @slinkydeveloper in #285
- Renaming components -> services by @slinkydeveloper in #287
- Implement Shared handlers annotation for virtual objects by @slinkydeveloper in #288
- Renamings 2 by @slinkydeveloper in #289
- Add "Start invocation" in InvocationStateMachine, symmetric with "End invocation" log line by @slinkydeveloper in #290
- Add checkEntryHeader to output entry by @slinkydeveloper in #291
- Propagate
otelContext
inRequest
and in thread-local/coroutine context by @slinkydeveloper in #296 - Remove Serde#schema by @slinkydeveloper in #298
- Add metadata by @slinkydeveloper in #299
- [Release] Bump to 0.9.0 by @github-actions in #300
Full Changelog: v0.8.0...v0.9.0
v0.8.0
What's Changed
- [Release] Bump to 0.7.1-SNAPSHOT by @github-actions in #203
- Upgrade gradle and add .ignore by @AhmedSoliman in #205
- Awakeable IDs following the new ID scheme by @AhmedSoliman in #204
- Isolate gRPC code by @slinkydeveloper in #195
- Support Kotlin target in the protoc plugin by @slinkydeveloper in #196
- Bumped testcontainers and vertx by @slinkydeveloper in #209
- Serialize state as JSON. by @slinkydeveloper in #208
Awaitable#map
by @slinkydeveloper in #210- Split RestateContext interface in KeyedContext/UnkeyedContext by @slinkydeveloper in #213
- Workflow API by @slinkydeveloper in #215
- Stop assuming input and output of invocations implement MessageLite by @slinkydeveloper in #214
KeyedContext#clearAll
by @slinkydeveloper in #217- Add
ctx.stateKeys()
by @slinkydeveloper in #219 - A bunch of fixes for the Workflow API by @slinkydeveloper in #222
- Add API to sdk-testing to mount workflows. by @slinkydeveloper in #223
- Rename
UnkeyedContext
toContext
by @slinkydeveloper in #220 - Fix suffix problem with workflow api. by @slinkydeveloper in #225
- Add support for kotlin serialization by @slinkydeveloper in #224
- Bump protocol version by @slinkydeveloper in #226
- Handler API by @slinkydeveloper in #227
- [Release] Bump to 0.8.0 by @github-actions in #232
New Contributors
- @AhmedSoliman made their first contribution in #205
Full Changelog: v0.7.0...v0.8.0
v0.7.0
What's Changed
- [Release] Bump to 0.7.0-SNAPSHOT by @github-actions in #182
- Update meta API by @slinkydeveloper in #186
- Fix logging context propagation by @slinkydeveloper in #185
- Update SDK to use restatedev/service-protocol#58 by @tillrohrmann in #189
- Log improvements by @slinkydeveloper in #194
- Introduce deterministic random by @slinkydeveloper in #178
- Use target/source compatibility rather than selecting a specific toolchain by @slinkydeveloper in #197
- Check protocol version is supported by @slinkydeveloper in #199
- [Release] Bump to 0.7.0 by @github-actions in #200
Full Changelog: v0.6.0...v0.7.0