Announcing the Restate Java SDK

Posted December 13, 2023 by Stephan Ewen and Giselle van Dongen and Pavel Tcholakov ‐ 4 min read

We are exited to announce the Java SDK for Restate today. You can now use the power of Restate for services running in the JVM. This was the most requested SDK from user conversations and polls, so we are happy to see this released today. 🥳

🎄Christmas present: While the SDK core is implemented in Java, there is also a dedicated API module for Kotlin, including support for Kotlin co-routines for asynchronous operations and suspension points.

As with the TypeScript SDK, you can run services either as [containerized] processes (on K8s or really any resource manager) or as functions on AWS Lambda.

Let’s take a look at some code that uses the SDK…

What does a Java Restate service look like?

The Java SDK is built on top of gRPC, to have a well-defined and evolvable way to specify service interfaces and message serialization. Java Restate services look like any other gRPC service and can be called with the normal tools: generated clients in any language, grpcurl, grpcui, etc. Services implemented in Java and in the TypeScript gRPC API talk to each other transparently (polyglot world, yay!)

Below is code snippet from our ‘Why we built Restate’ post, rewritten in Java. It reserves a ticket, updates a card, and schedules expiry, all reliably without any specific error handling. The function can recover partial progress and suspend while awaiting RPC response from the TicketService.

public class Cart extends CartRestate.CartRestateImplBase {

    // describes key and serde of for the state
    private static final StateKey<Set<String>> STATE_KEY =
            StateKey.of("cart", JacksonSerdes.of(new TypeReference<>(){}));

    @Override
    public BoolValue addTicketToCart(RestateContext ctx, TicketRequest request) {
        // try to reserve the ticket
        var ticket = Ticket.newBuilder().setTicketId(request.getTicketId()).build();
        var ticketClnt = TicketServiceRestate.newClient(ctx);
        var success = ticketClnt.reserve(ticket).await();

        if (success.getValue()) {
            // update the local state (cart contents)
           Set<String> tickets = ctx.get(STATE_KEY).orElseGet(HashSet::new);
           tickets.add(request.ticketId);
           ctx.set(STATE_KEY, tickets);

           // schedule expiry timer
           var cartClnt = CartRestate.newClient(ctx);
           cartClnt.delayed(Duration.ofMinutes(15)).expireTicket(request);
        }

        return success;
    }
}

If you’ve worked with gRPC in Java, you’ll notice that the code doesn’t look like the output of standard Java protoc. We have added a Restate plugin to protoc which makes the output more streamlined and enables direct access to the RestateContext. Though you can also use vanilla protoc-generated code with Restate if you prefer that!

It is worth pointing out that Restate doesn’t use actual gRPC servers or network code, but only the generated code for services, messages, and clients.

What can I build with this?

The Restate Java SDK is full-featured and lets you create all the types of applications that Restate supports:

  • Workflows as simple service methods, deployed as suspendable serverless functions on AWS Lambda, or as long-lived stateless processes on Kubernetes (or any other resource platform).
  • Services with durable execution and communication. Applications are written as simple gRPC services, but get the benefits of asynchronous execution using durable logs or message queues: reliable communication, resilience, decoupling. But without the hassle of managing state machines, queue/log semantics, partitioning, head-of-the-line waiting, message deferring, etc. Take an RPC app and give it the benefits of an event-driven architecture.
  • Event-processing with Kafka: Service methods can be triggered by messages from Kafka (exactly-once) just like from gRPC or HTTP. Applications are expressed as durable event handlers (think fast micro-workflows) instead of stream processing DAGs.
  • Or any mix of the above – this is where things get really interesting! Workflows orchestrating stateful services through reliable exactly-once channels. State machines that are driven by a mix of RPC calls and Kafka events. Stateful serverless handlers on Lambda directly triggered from Kafka.

Getting started with the Java SDK

If you want to create a sample app with the Restate Java SDK, the fastest way to get started is to start from a template, like the Hello World Gradle template. This also manages the gRPC code gen for you.

Alternatively, you can add the Restate SDK as a dependency to any Gradle/Maven/SBT project by adding the SDK dependencies, as described in the SDK Readme.

We are eager to hear how you experience the new Java SDK!


Join the community and help shape Restate!

Join our Discord!