Workflow message passing - Java SDK
A Workflow can act like a stateful web service that receives messages: Queries, Signals, and Updates. The Workflow implementation defines these endpoints via handler methods that can react to incoming messages and return values. Temporal Clients use messages to read Workflow state and control execution. See Workflow message passing for a general overview of this topic. This page introduces these features for the Temporal Java SDK.
Write message handlersβ
Follow these guidelines when writing your message handlers:
- Message handlers are defined as methods on the Workflow class, using one of the three annotations:
@QueryMethod
,@SignalMethod
, and@UpdateMethod
. - The parameters and return values of handlers and the main Workflow function must be serializable.
- Prefer a single class with multiple fields over using multiple input parameters. A class allows you to add fields without changing the calling signature.
Query handlersβ
A Query is a synchronous operation that retrieves state from a Workflow Execution:
public class MessagePassingIntro {
public enum Language {
CHINESE,
ENGLISH,
FRENCH,
SPANISH,
PORTUGUESE,
}
public static class GetLanguagesInput {
public boolean includeUnsupported;
public GetLanguagesInput() {
this.includeUnsupported = false;
}
public GetLanguagesInput(boolean includeUnsupported) {
this.includeUnsupported = includeUnsupported;
}
}
@WorkflowInterface
public interface GreetingWorkflow {
...
// π Use the @QueryMethod annotation to define a Query handler in the
// Workflow interface.
@QueryMethod
List<Language> getLanguages(GetLanguagesInput input);
}
public static class GreetingWorkflowImpl implements GreetingWorkflow {
...
@Override
public List<Language> getLanguages(GetLanguagesInput input) {
// π The Query handler returns a value: it must not mutate the Workflow state
// or perform blocking operations.
if (input.includeUnsupported) {
return Arrays.asList(Language.values());
} else {
return new ArrayList(greetings.keySet());
}
}
}
}
- A Query handler must not modify Workflow state.
- You can't perform blocking operations such as executing an Activity in a Query handler.
- The Query annotation accepts an argument (
name
) as described in the API reference docs for@QueryMethod
.
Signal handlersβ
A Signal is an asynchronous message sent to a running Workflow Execution to change its state and control its flow:
public class MessagePassingIntro {
public static class ApproveInput {
private String name;
public ApproveInput() {}
public ApproveInput(String name) {
this.name = name;
}
}
@WorkflowInterface
public interface GreetingWorkflow {
...
// π Use the @SignalMethod annotation to define a Signal handler in the
// Workflow interface.
@SignalMethod
void approve(ApproveInput input);
}
public static class GreetingWorkflowImpl implements GreetingWorkflow {
...
@Override
public Language setLanguage(Language language) {
// π The Signal handler mutates the Workflow state but cannot return a value.
Language previousLanguage = this.language;
this.language = language;
return previousLanguage;
}
}
}
-
The handler should not return a value. The response is sent immediately from the server, without waiting for the Workflow to process the Signal.
-
The Signal annotation accepts arguments (
name
, andunfinished_policy
) as described in the API reference docs for@SignalMethod
. -
Signal (and Update) handlers can be blocking. This allows you to use Activities, Child Workflows, durable
Workflow.sleep
Timers,Workflow.await
, and more. See Blocking handlers and Workflow message passing for guidelines on safely using blocking Signal and Update handlers.