Nexus Microservice Development Walkthrough - Java SDK
This walkthrough covers the Temporal Operation Handler, which is pre-release. APIs are experimental and may change in backwards-incompatible ways.
This walkthrough builds one Nexus Service from nothing to a complete API, adding a single Nexus capability at each step.
A Nexus Service is a contract that one team publishes and other teams call, across Namespace boundaries, without sharing code or a deployment.
The walkthrough problem
This guide creates a purchase approval Workflow — a common Temporal and Nexus use case.
A purchase request needs approval before it can proceed.
Approval is slow and human-driven: someone has to look at the request and decide. The system needs to survive that wait, which may be minutes or weeks. While a request is pending, other systems might need to nudge the approver or attach information to the request. Eventually a decision arrives, and the requesting system needs the outcome.
Concretely, the Service needs to:
- Tell a caller whether a purchase needs approval at all, before any durable work starts
- Start an approval and, eventually, return
APPROVEDorDENIED - Accept a nudge that asks the approver again, and count how many have been sent
- Accept supporting information for a purchase, whether or not its approval exists yet
- Accept a decision from the caller and confirm it was recorded
- Send a notification when the decision is final
Each of those needs a different Nexus capability, introduced one step at a time.
One contract, every language
This walkthrough builds the Service in Java. The same contract has a sample implementation in every language the generator supports. The reasoning at each step — what the contract should say, what backs each Operation, which message type to reach for — is the same in all of them.
Working sample code, all built from the one contract:
| Language | Sample |
|---|---|
| Java (this walkthrough) | nexuswalkthrough |
| Go | {sample repo link} |
| Python | {sample repo link} |
| TypeScript | {sample repo link} |
Any caller can call any handler, because the contract is the only thing the two sides share. A Go caller can drive the Python handler; the TypeScript caller can drive the Java handler. Step 6 builds the Java caller and then points at the other languages' samples.
Sample repos for each language will land once the docs settle. The idea is that you can run the client from any sample against the handler from any other sample.
The Nexus Client Code Generator takes the contract and emits typed models, validators, and Service definitions for Go, Java, Python, and TypeScript.
How to follow along
Two kinds of code block appear in this walkthrough. Mousing over either will give you a copy icon to the right of the code block.
A terminal window is a command to run. This one is worth running now, to confirm you have a pre-release CLI. Make sure the server version is 1.32.0 or higher:
temporal --version
Every terminal command has to be run, in order, or later steps may fail. Each step that adds an Operation also ends with a terminal window that exercises what you just built, so you get a result at the end of every step rather than after five steps of unverified work.
A block headed by a file path is sample code, shown so you can read it. Nothing needs to be typed as this will be present in the sample codebase. The file name will a link to the file in the sample repo.
core/src/main/java/io/temporal/samples/nexuswalkthrough/handler/ApprovalWorkflowId.java
public static String forItem(String itemId) {
return "approval-" + itemId;
}
Output a command produces is shown in a plain block with no header, like this:
temporal version 1.8.3-server-1.32.0-162.0 (Server 1.32.0-162.0, UI 2.53.1)
Before you start
Clone the sample project
This walkthrough runs inside a clone of the samples-java repository. Every command and file path below is relative to the repository root, and the finished Service lives in core/src/main/java/io/temporal/samples/nexuswalkthrough.
git clone https://github.com/temporalio/samples-java.git
cd samples-java
The sample is the finished Service, so you can view and run the code in the repository to follow along with the guide. Each step shows the code it is introducing and then runs it.
Use the pre-release CLI
The Temporal Operation Handler is pre-release, so you need a pre-release Temporal CLI and the development server that ships with it which can be downloaded here. Check the what's changed section and ensure it is not a backport! A stock build currently rejects the Operations this walkthrough runs. See Debugging and tips for what each failure looks like.
Start the development server
Two dynamic config values are required:
temporal server start-dev \
--dynamic-config-value 'nexusoperation.enableStandalone=true' \
--dynamic-config-value 'activity.enableCallbacks=true'
nexusoperation.enableStandalone allows a Client to start an Operation without a caller Workflow,
which is how you run each Operation from the command line as you build it.
activity.enableCallbacks allows a completion callback on a Standalone Activity Execution, which
the notifyRequester Operation in step 9
needs.
Create the Namespaces and the Endpoint
Create these in a second terminal. The handler and the caller each get their own Namespace, so the walkthrough crosses a real Namespace boundary.
temporal operator namespace create --namespace approval-handler-namespace
temporal operator namespace create --namespace approval-caller-namespace
temporal operator nexus endpoint create \
--name approval-endpoint \
--target-namespace approval-handler-namespace \
--target-task-queue approval-handler-task-queue \
--description-file ./core/src/main/java/io/temporal/samples/nexuswalkthrough/description.md
Steo 5 explains what the Endpoint does and covers Temporal Cloud, where the same Endpoint also needs an allowed-caller list. Creating it now means every Operation is callable the moment you write it.
Run an Operation at the end of each step
Each step that adds an Operation ends by running it, so you get a result before moving on rather
than after five steps of unverified work. Those runs use temporal nexus operation execute, which
starts a Standalone Nexus Operation: the CLI is the caller, so no
caller Workflow and no caller Worker are needed until
step 6.
New to Nexus? Read Nexus Services and Nexus Operations, or work through the shorter Java Nexus quickstart.