Forwarding and effects

This page documents how to use Cloudstate effects and forwarding in Java. For high level information on what Cloudstate effects and forwarding is, please read the general forwarding and effects documentation first.

Looking up service call references

To forward a command or emit an effect, a reference to the service call that will be invoked needs to be looked up. This can be done using the ServiceCallFactory interface, which is accessible on any context object via the serviceCallFactory() method.

For example, if a user function serves two entity types, a shopping cart, and a CRDT that tracks which items are currently in hot demand, it might want to invoke the ItemAddedToCart command on example.shoppingcart.HotItems as a side effect of the AddItem shopping cart command. This reference can be looked up like so:

private final ServiceCallRef<Hotitems.Item> itemAddedToCartRef;

public ShoppingCartEntity(Context ctx) {
  itemAddedToCartRef =
      ctx.serviceCallFactory()
          .lookup(
              "example.shoppingcart.ShoppingCartService", "ItemAddedToCart", Hotitems.Item.class);
}

This could be looked up in the constructor of the entity, for later use, so it doesn’t have to be looked up each time it’s needed.

Forwarding command

The CommandContext for each entity type implements ClientActionContext to allow forwarding a command by invoking ClientActionContext.forward(). For example, if the item being processed in the addItem command is a "hot" item, we can make the HotItems entity aware of that item by forwarding a command:

@CommandHandler
public void addItem(Shoppingcart.AddLineItem item, CommandContext ctx) {
  // ... Validate and emit event

  ctx.forward(
      itemAddedToCartRef.createCall(
          Hotitems.Item.newBuilder()
              .setProductId(item.getProductId())
              .setName(item.getName())
              .setQuantity(item.getQuantity())
              .build()));
}

Emitting an effect

The CommandContext for each entity type implements EffectContext to allow emitting an effect by invoking EffectContext.effect(). For example, upon successful completion of the addItem command by ShoppingCartEntity, if we also want to emit an effect on the HotItems entity, we would invoke the effectful service call as:

@CommandHandler
public Empty addItem(Shoppingcart.AddLineItem item, CommandContext ctx) {
  // ... Validate and emit event

  ctx.effect(
      itemAddedToCartRef.createCall(
          Hotitems.Item.newBuilder()
              .setProductId(item.getProductId())
              .setName(item.getName())
              .setQuantity(item.getQuantity())
              .build()));

  return Empty.getDefaultInstance();
}

Please note that, contrary to command forwarding, the result of the effect is ignored by the current command addItem. More details in the common section Forwarding and effects