Skip to content

Commit

Permalink
docs: describe what an effect is
Browse files Browse the repository at this point in the history
  • Loading branch information
octonato committed Jan 9, 2024
1 parent c180dad commit 9f0f112
Show file tree
Hide file tree
Showing 28 changed files with 164 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ include::ROOT:partial$include.adoc[]
The main steps in developing a service include:

. <<_specify_service_interface_and_domain_model>>
. <<_effects_api>>
. <<_implement_components>>
. <<_create_unit_tests>>
. <<_package_service>>
Expand All @@ -26,12 +27,14 @@ The gRPC definitions in `.proto` files describe the external interface, messages
TIP: Kickstart a project using the xref:java-protobuf:quickstart-template.adoc[project template].
include::java-protobuf:partial$effects-api.adoc[]
[#_implement_components]
== Implement components
Stateful services can implement https://docs.kalix.io/reference/glossary.html#value_entity[Value Entity] or https://docs.kalix.io/reference/glossary.html#event_sourced_entity[Event Sourced Entity] and https://docs.kalix.io/reference/glossary.html#view[View] components. Stateless services implement https://docs.kalix.io/reference/glossary.html#action[Actions]. Typically, a stateful service should only have one Entity type, but can also include Actions and Views.
=== Actions
Actions are stateless functions that can be triggered by gRPC or HTTP calls. They can also subscribe to published events, and they can send commands to other services based on the events they receive. For more information about writing actions see xref:java-protobuf:actions.adoc[Implementing Actions].
Expand All @@ -48,6 +51,10 @@ TIP: For more information see xref:java-protobuf:actions-as-controller.adoc[Acti
Services can interact asynchronously with other services and with external systems. Event Sourced Entities emit events to a journal, to which other services can subscribe. By configuring your own publish/subscribe (pub/sub) mechanism, any service can publish their own events and subscribe to events published by other services or external systems.
=== Views
A View provides a way to retrieve state from multiple Entities based on a query. You can query non-key data items. You can create views from Value Entity state, Event Sourced Entity events, and by subscribing to topics. For more information about writing views see xref:java:views.adoc[Implementing Views].
For more details and examples take a look at the following topics:
* xref:java-protobuf:value-entity.adoc[Value Entities]
Expand Down
6 changes: 5 additions & 1 deletion docs/src/modules/java-protobuf/pages/actions.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
= Implementing Actions in Java
= Implementing Actions
:page-supergroup-java-scala: Language
:page-aliases: java-protobuf:actions-as-controller.adoc, java-protobuf:side-effects.adoc

Expand Down Expand Up @@ -35,6 +35,10 @@ include::example$scala-protobuf-fibonacci-action/src/main/proto/com/example/fibo
<2> Import the Kalix protobuf annotations or options.
<3> The protobuf option (kalix.codegen) is specific to code-generation as provided by the Kalix sbt plugin. This annotation indicates to the code-generation that an Action must be generated.

include::partial$effects-action.adoc[]

See also xref:developing:development-process-proto.adoc#_effects_api[Understanding what an Effect is]

== Implementing the Action

An Action implementation is a class where you define how each message is handled. The class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ include::example$scala-protobuf-eventsourced-shopping-cart/src/main/proto/com/ex
<11> `state` points to the protobuf message representing the entity's state which is kept by Kalix. It is stored as snapshots.
<12> `events` points to the protobuf message representing the entity's events, which are stored by Kalix.

include::java-protobuf:partial$effects-event-sourced-entity.adoc[]

See also xref:developing:development-process-proto.adoc#_effects_api[Understanding what an Effect is]

== Implementing behavior

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ include::example$scala-protobuf-replicatedentity-shopping-cart/src/main/proto/co
<12> `key` points to the protobuf message representing the counter map's key type.


include::partial$effects-replicated-entity.adoc[]

See also xref:developing:development-process-proto.adoc#_effects_api[Understanding what an Effect is]

== Implementing behavior

A Replicated Entity implementation is a Java class where you define how each command is handled. The class `ShoppingCart` gets generated for us based on the `shoppingcart_api.proto` and `shoppingcart_domain.proto` definitions. Once the file [.group-java]#`ShoppingCart.java`# [.group-scala]#`ShoppingCart.scala`# exist, it is not overwritten, so you can freely add logic to it. `ShoppingCart` extends the generated class `AbstractShoppingCart` which we're not supposed to change as it gets regenerated in case we update the protobuf descriptors. `AbstractShoppingCart` contains all method signatures corresponding to the API of the service. If you change the API you will see compilation errors in the `ShoppingCart` class and you have to implement the methods required by `AbstractShoppingCart`.
Expand Down
3 changes: 3 additions & 0 deletions docs/src/modules/java-protobuf/pages/value-entity.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ include::example$scala-protobuf-valueentity-counter/src/main/proto/com/example/c
<10> `entity_type` is a unique identifier of the "state storage." The entity name may be changed even after data has been created, the `entity_type` can't.
<11> `state` points to the protobuf message representing the Value Entity's state which is kept by Kalix. Note, the package and name follow the definition in the domain.proto file.

include::partial$effects-value-entity.adoc[]

See also xref:developing:development-process-proto.adoc#_effects_api[Understanding what an Effect is]

== Implementing behavior

Expand Down
6 changes: 5 additions & 1 deletion docs/src/modules/java-protobuf/pages/views.adoc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
= Implementing Views in Java or Scala
= Implementing Views
:page-supergroup-java-scala: Language
include::ROOT:partial$include.adoc[]

Expand All @@ -18,6 +18,10 @@ The remainder of this page describes:
IMPORTANT: Be aware that Views are not updated immediately when Entity state changes. Kalix does update Views as quickly as possible. It is not instant but eventually all changes will become visible in the query results. View updates might also take more time during failure scenarios than during normal operation.

include::java-protobuf:partial$effects-view.adoc[]

See also xref:developing:development-process-proto.adoc#_effects_api[Understanding what an Effect is]

[#value-entity]
== Creating a View from a Value Entity

Expand Down
11 changes: 11 additions & 0 deletions docs/src/modules/java-protobuf/partials/effects-action.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
== Action's Effect API

The Action's Effect defines the operations that Kalix should perform when an incoming message is handled by an Action.

An Action Effect can either:

* reply with a message to the caller
* reply with a message to be published to a topic (in case the method is a publisher)
* forward the message to another component
* return an error
* ignore the call
11 changes: 11 additions & 0 deletions docs/src/modules/java-protobuf/partials/effects-api.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

[#_effects_api]
== Understanding what an Effect is
Each component defines a set of operations through its application programming interface (API). These operations are specific to the semantics of each component. For the JVM SDKs, these APIs take the shape of an Effect.
An Effect is a description of what Kalix needs to do after an incoming command is handled. You can think of it as a set of instructions you are passing to Kalix. Kalix will process the instructions on your behalf.
The component Effect APIs play a central role when implementing a component as it provides the glue between your application logic and Kalix. For a more high-level overview of Kalix Architecture Style, check out the https://docs.kalix.io/concepts/programming-model.html[Programming model] page.
The details of each component Effect type are explained in the component's specific pages.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
== Event Sourced Entity's Effect API

The Event Sourced Entity's Effect defines the operations that Kalix should perform when an incoming command is handled by an Event Sourced Entity.

An Event Sourced Entity Effect can either:

* emit events and send a reply to the caller
* directly reply to the caller if the command is not requesting any state change
* rejected the command by returning an error
* instruct Kalix to delete the entity
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
== Replicated Entity's Effect API

The Replicated Entity's Effect defines the operations that Kalix should perform when an incoming command is handled by a Replicated Entity.

A Replicated Entity Effect can either:

* update the entity state and send a reply to the caller
* directly reply to the caller if the command is not requesting any state change
* rejected the command by returning an error
* instruct Kalix to delete the entity
10 changes: 10 additions & 0 deletions docs/src/modules/java-protobuf/partials/effects-value-entity.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
== Value Entity's Effect API

The Value Entity's Effect defines the operations that Kalix should perform when an incoming command is handled by a Value Entity.

A Value Entity Effect can either:

* update the entity state and send a reply to the caller
* directly reply to the caller if the command is not requesting any state change
* rejected the command by returning an error
* instruct Kalix to delete the entity
9 changes: 9 additions & 0 deletions docs/src/modules/java-protobuf/partials/effects-view.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
== View's Effect API

The View's Effect defines the operations that Kalix should perform when an event, a message or a state change is handled by a View.

A View Effect can either:

* update the view state
* delete the view state
* ignore the event or state change notification (and not update the view state)
12 changes: 12 additions & 0 deletions docs/src/modules/java-protobuf/partials/effects-workflow.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
== Workflow's Effect API

The Workflow's Effect defines the operations that Kalix should perform when an incoming command is handled by a Workflow.

A Workflow Effect can either:

* update the state of the workflow
* define the next step to be executed (transition)
* pause the workflow
* end the workflow
* fail the step or reject a command by returning an error
* reply to incoming commands
4 changes: 4 additions & 0 deletions docs/src/modules/java/pages/actions.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
include::ROOT:partial$include.adoc[]
include::java-protobuf:partial$actions.adoc[]

include::java-protobuf:partial$effects-action.adoc[]

See also xref:java:development-process.adoc#_effects_api[Understanding what an Effect is]

== Actions as Pure Functions

In this first example, you will learn how to implement an Action as a pure stateless function. You will create a `FibonacciAction` that takes a number and returns the
Expand Down
14 changes: 14 additions & 0 deletions docs/src/modules/java/pages/development-process.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ include::ROOT:partial$include.adoc[]

The main steps in developing a service include:

. <<_effects_api>>
. <<_implement_components>>
. <<_create_unit_tests>>
. <<_package_service>>
Expand All @@ -17,19 +18,22 @@ The main steps in developing a service include:
The main components of a Kalix service are:
* Stateful https://docs.kalix.io/reference/glossary.html#entity[Entities]
* Stateful https://docs.kalix.io/reference/glossary.html#Workflow[Workflows]
* Stateless https://docs.kalix.io/reference/glossary.html#action[Actions]
* https://docs.kalix.io/reference/glossary.html#view[Views], which return the state of multiple instances of a stateful entity.
We recommend that you separate the service API and Entity domain data model. Separating the service interface and data model in different classes allows you to evolve them independently.
TIP: Kickstart a project using the xref:java:getting-started.adoc[Getting started] guide.
include::java-protobuf:partial$effects-api.adoc[]
[#_implement_components]
== Implement components
Stateful services can implement https://docs.kalix.io/reference/glossary.html#value_entity[Value Entity] or https://docs.kalix.io/reference/glossary.html#event_sourced_entity[Event Sourced Entity] and https://docs.kalix.io/reference/glossary.html#view[View] components. Stateless services implement https://docs.kalix.io/reference/glossary.html#action[Actions]. Typically, a stateful service should only have one Entity type, but can also include Actions and Views.
=== Actions
Actions are stateless functions that can be triggered by HTTP calls. They can also subscribe to published events, and they can send commands to other services based on the events they receive. For more information about writing actions see xref:java:actions.adoc[Implementing Actions].
Expand All @@ -46,10 +50,20 @@ TIP: For more information see xref:java:actions-as-controller.adoc[Actions as Co
Services can interact asynchronously with other services and with external systems. Event Sourced Entities emit events to a journal, to which other services can subscribe. By configuring your own publish/subscribe (pub/sub) mechanism, any service can publish their own events and subscribe to events published by other services or external systems.
=== Workflows
Kalix Workflows are high-level descriptions to easily align business requirements with their implementation in code. Orchestration across multiple services with support for failure scenarios and compensating actions is simple with Kalix Workflows.
=== Views
A View provides a way to retrieve state from multiple Entities based on a query. You can query non-key data items. You can create views from Value Entity state, Event Sourced Entity events, and by subscribing to topics. For more information about writing views see xref:java:views.adoc[Implementing Views].
For more details and examples take a look at the following topics:
* xref:java:value-entity.adoc[Value Entities]
* xref:java:event-sourced-entities.adoc[Event Sourced Entities]
* xref:java:workflows.adoc[Workflows]
* xref:java:actions.adoc[Actions]
* xref:java:views.adoc[Views]
[#_create_unit_tests]
== Testing your application
Expand Down
4 changes: 4 additions & 0 deletions docs/src/modules/java/pages/event-sourced-entities.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ IMPORTANT: The use of logical names for subtypes is essential for maintainabilit

include::partial$entity-ids.adoc[]

include::java-protobuf:partial$effects-event-sourced-entity.adoc[]

See also xref:java:development-process.adoc#_effects_api[Understanding what an Effect is]

== Implementing behavior

Now that we have our Entity state defined along with its events, the remaining steps can be summarized as follows:
Expand Down
4 changes: 4 additions & 0 deletions docs/src/modules/java/pages/value-entity.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ include::example$java-spring-valueentity-counter/src/main/java/com/example/Numbe

include::partial$entity-ids.adoc[]

include::java-protobuf:partial$effects-value-entity.adoc[]

See also xref:java:development-process.adoc#_effects_api[Understanding what an Effect is]

[#entity-behavior]
== Implementing behavior

Expand Down
4 changes: 4 additions & 0 deletions docs/src/modules/java/pages/views.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ The remainder of this page describes:
IMPORTANT: Be aware that Views are not updated immediately when Entity state changes. Kalix does update Views as quickly as possible. It is not instant but eventually all changes will become visible in the query results. View updates might also take more time during failure scenarios than during normal operation.

include::java-protobuf:partial$effects-view.adoc[]

See also xref:java:development-process.adoc#_effects_api[Understanding what an Effect is]

[#value-entity]
== Creating a View from a Value Entity

Expand Down
4 changes: 4 additions & 0 deletions docs/src/modules/java/pages/workflows.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ It will often be necessary to access the generated id from inside the workflow c

NOTE: Kalix generates a UUID version 4 (random) keys. Only version 4 UUIDs are currently supported for generated Workflow identifiers.

include::java-protobuf:partial$effects-workflow.adoc[]

See also xref:java:development-process.adoc#_effects_api[Understanding what an Effect is]

== Modeling state

We want to build a simple workflow that transfers funds between two wallets. Before that, we will create a wallet subdomain with some basic functionalities that we could use later. For simplicity a `WalletEntity` is implemented as a `ValueEntity`, but for a production-ready solution an `EventSourcedEntity` would be a better choice.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ public final TimerScheduler timers() {
* <li>ignore the call
* </ul>
*
* A return type to allow returning forwards or failures, and attaching effects to messages.
*
* @param <T> The type of the message that must be returned by this call.
*/
public interface Effect<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ protected final Effect.Builder<S, E> effects() {
* <li>instruct Kalix to delete the entity
* </ul>
* <p>
* A return type to allow returning forwards or failures, and attaching effects to messages.
*
* @param <T> The type of the message that must be returned by this call.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,21 @@ protected final <R> Effect.Builder<D> effects() {
}

/**
* A return type to allow returning forwards or failures, and attaching effects to messages.
* An Effect is a description of what Kalix needs to do after the command is handled.
* You can think of it as a set of instructions you are passing to Kalix. Kalix will process the instructions on your
* behalf and ensure that any data that needs to be persisted will be persisted.
* <p>
* Each Kalix component defines its own effects, which are a set of predefined
* operations that match the capabilities of that component.
* <p>
* A Replicated Effect can either:
* <p>
* <ul>
* <li>update the entity state and send a reply to the caller
* <li>directly reply to the caller if the command is not requesting any state change
* <li>rejected the command by returning an error
* <li>instruct Kalix to delete the entity
* </ul>
*
* @param <R> The type of the reply message that must be returned by this call.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,6 @@ protected final Effect.Builder<S> effects() {
* <li>instruct Kalix to delete the entity
* </ul>
*
* A return type to allow returning forwards or failures, and attaching effects to messages.
*
* @param <T> The type of the message that must be returned by this call.
*/
public interface Effect<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ protected final Effect.Builder<S> effects() {
* Each Kalix component defines its own effects, which are a set of predefined
* operations that match the capabilities of that component.
* <p>
* A Workflow Effect can:
* A Workflow Effect can either:
* <p>
* <ul>
* <li>update the state of the workflow
Expand All @@ -165,9 +165,8 @@ protected final Effect.Builder<S> effects() {
* <li>reply to incoming commands
* </ul>
* <p>
* A return type to allow returning failures or attaching effects to messages.
*
* @param <T> The type of the message that must be returned by this call.
* @param <T> The type of the message that must be returned by this call.
*/
public interface Effect<T> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@ object Action {
* - return an error
* - ignore the call
*
* A return type to allow returning forwards or failures, and attaching effects to messages. A return type to allow
* returning forwards or failures, and attaching effects to messages.
*
* @tparam T
* The type of the message that must be returned by this call.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ object EventSourcedEntity {
* - rejected the command by returning an error
* - instruct Kalix to delete the entity
*
* A return type to allow returning forwards or failures, and attaching effects to messages.
*
* @tparam T
* The type of the message that must be returned by this call.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,19 @@ object ReplicatedEntity {
}

/**
* A return type to allow returning forwards or failures, and attaching effects to messages.
* An Effect is a description of what Kalix needs to do after the command is handled. You can think of it as a set of
* instructions you are passing to Kalix. Kalix will process the instructions on your behalf and ensure that any data
* that needs to be persisted will be persisted.
*
* Each Kalix component defines its own effects, which are a set of predefined operations that match the capabilities
* of that component.
*
* A Replicated Effect can either:
*
* - update the entity state and send a reply to the caller
* - directly reply to the caller if the command is not requesting any state change
* - rejected the command by returning an error
* - instruct Kalix to delete the entity
*
* @tparam T
* The type of the message that must be returned by this call.
Expand Down
Loading

0 comments on commit 9f0f112

Please sign in to comment.