Handler Parameters

Inside projections, Factus uses methods annotated with @Handler or @HandlerFor to process events. These methods allow various parameters, also in combination, which can serve as “input” during event handling.

Common Handler Parameters

Parameter Type & AnnotationDescriptionvalid on @Handlervalid on @HandlerFor
FactProvides access to all Fact details including header (JSON) and payload (JSON)yesyes
FactHeaderthe Fact header. Provides access to event namespace, type, version, meta entries and othersyesyes
UUIDthe Fact ID of the Fact headeryesyes
FactStreamPositionthe FactStreamPosition that identifies the position of the given fact in the global fact streamyesyes
@Nullable @Meta("foo") Stringif present, the value of the fact-header’s meta object attribute “foo”, otherwise nullyesyes
@Meta("foo") Optional<String>if present, the value of the fact-header’s meta object attribute “foo” wrapped in an Optional, otherwise Optional.emptyyesyes
? extends EventObjectan instance of a concrete class implementing EventObject.yesno

Extras on Redis atomic Projections

Additional to these common parameters, Projections can add parameters to be used by handler methods. For instance handler methods on @RedisTransactional projections that should use:

Parameter TypeDescriptionvalid on @Handlervalid on @HandlerFor
RTransactionneeded in a Redis transactional projectionyesyes

Examples

@Handler

Here are some examples:

// handle the "SomeThingStarted" event.
// deserialization happened automatically
@Handler
void apply(SomethingStarted event) {
    var someValue = event.getSomeProperty();
    ...
}

// handle the "SomethingChanged" event.
// additionally use information from the Fact header
@Handler
void apply(SomethingChanged event, FactHeader header) {
    int eventVersion = header.version();
    String someMetaDataValue = header.meta().get("some-metadata-key");
    ...
}

// use multiple parameters
@Handler
void apply(SomethingReactivated event,
           FactHeader factHeader,
           UUID factId,
           Fact fact) {
    ...
}

These examples were all based on handling events which

The next section introduces a more direct alternative.

@HandlerFor

The @HandlerFor annotation allows only direct access to the Fact data like header or payload without any deserialization.

// handle "SomethingAdded" events in their version 1
// living in the "test" namespace
@HandlerFor(ns = "test", type = "SomethingAdded", version = 1)
void applySomethingAdded(Fact fact) {
    String payload = fact.jsonPayload();
    ...
}

// also here, multiple parameters can be used
@HandlerFor(ns = "test", type = "SomethingRemoved", version = 2)
void applySomethingRemoved(FactHeader factHeader, UUID factId, Fact fact) {
    ...
}

Full Example

See here for the full example.