Forwarding and effects
This page documents how to use Cloudstate effects and forwarding in Go. For high level information on what Cloudstate effects and forwarding is, please read the general forwarding and effects documentation first.
Service References
Unlike other language support libraries, the Go Support Library for Cloudstate is quite explicit and direct in the API types used. The Forwarding and effects API being no different.
The Go gRPC protobuf compiler plugin doesn’t expose service descriptors. As a consequence, command, forward and effect handlers require the user to provide unchecked plain strings to reference a commands gRPC service name or services method names. The same applies for service names and command names used with effects and forwards.
Forwarding command
The Context
for each entity type provides a Forward
method to allow forwarding a command by invoking crdt.CommandContext.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:
switch cmd {
case "Forward":
switch c := cmd.(type) {
case *shoppingcart.AddLineItem:
any, err := encoding.MarshalAny(&shoppingcart.Item{
ProductId: c.GetProductId(),
Name: c.GetName(),
Quantity: c.GetQuantity(),
})
if err != nil {
return nil, err
}
ctx.Forward(&protocol.Forward{
ServiceName: "example.shoppingcart.HotItemsService",
CommandName: "ItemAddedToCart",
Payload: any,
})
}
return encoding.Empty, nil
Emitting an effect
The Context
for each entity type provides a SideEffect
method to allow forwarding a command by invoking crdt.CommandContext.SideEffect
.
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:
case "Effect":
switch c := cmd.(type) {
case *shoppingcart.AddLineItem:
any, err := encoding.MarshalAny(&shoppingcart.Item{
ProductId: c.GetProductId(),
Name: c.GetName(),
Quantity: c.GetQuantity(),
})
if err != nil {
return nil, err
}
ctx.SideEffect(&protocol.SideEffect{
ServiceName: "example.shoppingcart.HotItemsService",
CommandName: "ItemAddedToCart",
Payload: any,
Synchronous: true,
})
}
return encoding.Empty, nil
Please note that, contrary to command forwarding, the result of the effect is ignored by the current command addItem
.
More details can be found in the common section Forwarding and effects.