Implementing Restate services with the Java/Kotlin SDK.
The Restate Java/Kotlin SDK is open source and available on GitHub.The Restate SDK lets you implement handlers. Handlers can be part of a Basic Service, a Virtual Object, or a Workflow. This page shows how to define them with the Java/Kotlin SDK.
Get started quickly with the Java or Kotlin Quickstart.
To start building Restate services, you need two dependencies in your Maven/Gradle project manifest:
The SDK dependency.
The annotation processor dependency.
The SDK dependency comes in different flavors: Java or Kotlin API, HTTP or Lambda.
Choose the one you need depending on the language you want to use and whether you want to deploy the service as an HTTP server or as AWS Lambda.
// Annotation processorannotationProcessor("dev.restate:sdk-api-gen:2.4.1")// For deploying as HTTP serviceimplementation("dev.restate:sdk-java-http:2.4.1")// Or for deploying using AWS Lambdaimplementation("dev.restate:sdk-java-lambda:2.4.1")
<properties> <restate.version>2.4.1</restate.version></properties><dependencies> <!-- For deploying as HTTP service --> <dependency> <groupId>dev.restate</groupId> <artifactId>sdk-java-http</artifactId> <version>${restate.version}</version> </dependency> <!-- For deploying using AWS Lambda --> <dependency> <groupId>dev.restate</groupId> <artifactId>sdk-java-lambda</artifactId> <version>${restate.version}</version> </dependency></dependencies><build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <!-- Setup annotation processor --> <path> <groupId>dev.restate</groupId> <artifactId>sdk-api-gen</artifactId> <version>${restate.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins></build>
// KSP annotation processorksp("dev.restate:sdk-api-kotlin-gen:2.4.1")// For deploying as HTTP serviceimplementation("dev.restate:sdk-kotlin-http:2.4.1")// Or for deploying using AWS Lambdaimplementation("dev.restate:sdk-kotlin-lambda:2.4.1")
Troubleshooting: Cannot resolve symbol '<MyServiceName>Client'
Make sure the annotation processor is correctly configured, as described above, and build the project at least once.
IntelliJ won't update the Client classes when building
Make sure you have annotation processing enabled in the IntelliJ compiler, check the relevant documentation.
An example setup is available here: compiler.xml
Each handler can be called at <RESTATE_INGRESS>/MyService/myHandler. To override the service name (default is simple class name), use the annotation @Name.
Workflows are long-lived processes with a defined lifecycle. They run once per key and are ideal for orchestrating multi-step operations, which require external interaction via signals and queries.
@Workflowpublic class MyWorkflow { @Workflow public String run(WorkflowContext ctx, String input) { // implement workflow logic here return "success"; } @Shared public String interactWithWorkflow(SharedWorkflowContext ctx, String input) { // implement interaction logic here return "my result"; } public static void main(String[] args) { RestateHttpServer.listen(Endpoint.bind(new MyWorkflow())); }}
@Workflowclass MyWorkflow { @Workflow suspend fun run(ctx: WorkflowContext, input: String): String { // implement workflow logic here return "success" } @Handler suspend fun interactWithWorkflow(ctx: SharedWorkflowContext, input: String): String { // implement interaction logic here return "my result" }}fun main() { RestateHttpServer.listen(endpoint { bind(MyWorkflow()) })}
Create the workflow by using the @Workflow annotation.
Every workflow must include a run handler:
This is the main orchestration entry point
It runs exactly once per workflow execution and uses the WorkflowContext (JavaDocs/KotlinDocs)
Resubmission of the same workflow will fail with “Previously accepted”. The invocation ID can be found in the request header x-restate-id.
Use ctx.key() to access the workflow’s unique ID
Additional handlers must use the SharedWorkflowContext (JavaDocs/KotlinDocs) and can signal or query the workflow. They can run concurrently with the run handler and until the retention time expires.