Skip navigation links

@CheckReturnValue @ParametersAreNonnullByDefault

Package io.spine.server.tuple

This package provides classes for return values from message-handling methods.

See: Description

Package io.spine.server.tuple Description

This package provides classes for return values from message-handling methods.


Although tuples are considered harmful in general, they are useful for describing types of several messages returned by a method. Consider the following example.

The return value of the below method does not say much about the number and types of returned event messages. We just know that there may be more than one of them.

     List<EventMessage> on(CreateTask cmd) { ... }
The below declaration gives both the number and types of the returned events:
     Pair<TaskCreated, Optional<TaskAssigned>> on(CreateTask cmd) { ... }

Why do we suggest returning a tuple (a Pair in the example above) instead of creating a message type which would aggregate those of interest as our colleagues from the Guava team suggest?

Messages returned from a handling method are loosely coupled. They may not be created together all the time. The example above tells that TaskAssigned may not happen upon the creation of the task. It's possible that a task can be assigned sometime later. In this case combining returned messages does not reflect the domain language. Returning a tuple tells a part of the story in terms of the domain language right in the method signature. Details of this story are obtained from the method body.

It should be re-iterated that the purpose of this package is limited to the scenarios of handling messages. Programmers are strongly discouraged from using this package for other purposes.

Two groups of classes

This package provides two groups of classes:
  1. Tuple classes are for returning more than one message.
  2. Alternatives -- classes derived from Either -- are for returning only one message belonging the known set of types.

Generic Parameters

Classes provided by this package can support up to 5 generic parameters. These parameters are named from <A> through <E>. Types that can be passed to these parameters are described in the sections below.


The following tuple classes are provided:

The first generic parameter <A> must always be a specific Message class.

Tuple classes allow Optional starting from the second generic argument. The example below shows the method which always returns the TaskCreated event, and returns the TaskAssigned event only if the CreateTask command instructs to assign the task to a person.

     Pair<TaskCreated, Optional<TaskAssigned>> on(CreateTask cmd) { ... }


In some cases it is needed to return one message from a limited set of possible options. For example, the following method issues a command MoveToTrash if no work was reported on the task, and CancelTask if some work has been already logged.

     EitherOf2<MoveToTrash, CancelTask> handle(RemoveTask cmd) { ... }

In order to define alternatively returned values, please use the following classes:

Generic parameters for alternatives accept only Message classes.

We believe that a list of alternatives longer than five is hard to understand. If you face a such a need, consider splitting incoming message into two or more independent ones so that their outcome is more obvious.

Using Tuples with Alternatives

A Pair can be defined with the second parameter being one of the Either subclasses, and created using Pair.withEither().

Skip navigation links