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 ServiceCallFactorynew tab interface, which is accessible on any context object via the serviceCallFactory()new tab method.

For example, if a service implementation serves two entity types, an event sourced shopping cart, and a Replicated Entity 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.forwardnew tab. 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.effectnew tab. 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. Learn more about Using forwarding and effects