Skip to content

Java: flows #1793

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions java/flows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
synopsis: >
Learn about the flow feature in CAP Java.
status: released
---

# Flow: Modeling State Transitions <Beta /> <Since version="4.0.0" of="com.sap.cds:cds-feature-flow" />
<style scoped>
h1:before {
content: "Java"; display: block; font-size: 60%; margin: 0 0 .2em;
}
</style>

{{ $frontmatter.synopsis }}

Use the flow feature to define flows in your CDS model. The feature ensures that transitions between states are explicitly modeled, validated, and performed in a controlled manner.

## Enabling Flows { #enabling-flows }

To use the flow feature, add a dependency to [cds-feature-flows](TODO) in the `srv/pom.xml` file of your service:

```xml
<dependency>
<groupId>com.sap.cds</groupId>
<artifactId>cds-feature-flows</artifactId>
<scope>runtime</scope>
</dependency>
```

## Modeling Flows { #modeling-flows }

Flows are defined in the CDS model using annotations. Flows consist out of one status element and one or more _flow_ actions. Annotate the status element with `@flow.status`. Define all transitions as bound actions (TODO link /cap/docs/cds/cdl#bound-actions), list the valid entry states using `@flow.from` and the target state using `@flow.to`.

::: tip Best Practice
We recommend to always use `@flow.status` in combination with `@readonly`.
This gives full control over all transitions to the flow feature.
:::

### Details
Let's dive into the details of the annotations:

`@flow.status`
- This annotation is mandatory.
- The annotated element must be either an enum or an association to an enum.
- Only one status element per entity is supported.
- Draft-enabled entities are supported.
- `null` is **not** a valid state. Model your empty state explicitly.

`@flow.from`
- This annotation is optional. Leave it out and all states are valid entry states.
- This annotation's value type is an array. Each array element's type must match the status element.

`@flow.to`
- This annotation is optional. Leave it out and the target state is the entry state.
- This annotation's value type must match the status element.

Please note, while both `@flow.from` and `@flow.to` are optional, one of them is mandatory to mark the action as a flow action.

## Using and Extending Flows
When using the flow feature, default handlers (todo link /docs/java/cqn-services/application-services#implement-event-handler) are provided for your flow actions.

The default `Before` handler will validate that your entity instance is in a valid entry state. A validation error will return a 409 Http Status Code.

The default `On` handler will complete the action for void return types.

The default `After` handler will process the transition and update the status to the target state.

### Custom Event Handler { #custom-event-handler}
You can extend the default flow handlers with an event handler to implement custom event logic that should run on a transition.

TODO: node example: less than 100, more than 100

TODO: does readonly mean using the persistence service in custom handlers?


## Sample { #sample }

Let's take a look at the [CAP SFLIGHT App](https://github.com/SAP-samples/cap-sflight) sample and how we can update it using the flow feature.

Let's add `cds-feature-flow` to the dependencies.

Annotate the travel status element with the `@flow.status` annotation. Following is an extract of the relevant parts of the entity model:

```cds
entity Travel : managed {
key TravelUUID : UUID;
TravelID : Integer default 0 @readonly;
@flow.status
TravelStatus : Association to TravelStatus default 'O' @readonly;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TravelStatus is not shown in the example and seems to be an intermediate CodeList

};

entity TravelStatus : CodeList {
key code : TravelStatusCode;
}

type TravelStatusCode : String(1) enum {
Open = 'O';
Accepted = 'A';
Canceled = 'X';
};
```

Now, let's have a look at the added flow annotations in the service model:

```cds
service TravelService @(path:'/processor') {

entity Travel as projection on my.Travel actions {
@(flow: {
from:[ Open ],
to: Canceled
})
action rejectTravel();
@(flow: {
from:[ Open ],
to: Accepted
})
action acceptTravel();
};

}
```

Finally, in the CAP SFLIGHT App, no action handler is needed. All of the logic is taken care of by the flow feature. The flow feature will validate that entry state is `Open`. The flow feature will transit the status to `Accepted` and `Canceled` respectively.
If you followed along, with the CAP SFLIGHT App, simply remove the [AcceptRejectHandler](https://github.com/SAP-samples/cap-sflight/blob/main/srv/src/main/java/com/sap/cap/sflight/processor/AcceptRejectHandler.java).

TODO: validate that draft will work the same as in contracts/tests. It looks different here.




Loading