Skip to content
Merged

@assert #2216

Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
58b81af
content
StefanHenke Nov 19, 2025
6ca8d04
Update guides/providing-services.md
StefanHenke Nov 20, 2025
f5f5f84
incorporate feedback
StefanHenke Nov 20, 2025
1953da0
fix cds syntax
StefanHenke Nov 20, 2025
c17c192
Update guides/providing-services.md
StefanHenke Nov 21, 2025
7bffed3
real life samples
StefanHenke Nov 21, 2025
e77e067
fix cds syntac
StefanHenke Nov 21, 2025
baa450c
Update guides/providing-services.md
StefanHenke Nov 24, 2025
7c18cb5
Update guides/providing-services.md
StefanHenke Nov 24, 2025
c368a2b
Update guides/providing-services.md
StefanHenke Nov 24, 2025
1069742
Update guides/providing-services.md
rjayasinghe Nov 27, 2025
a929b44
Update guides/providing-services.md
rjayasinghe Nov 27, 2025
9be2cc2
Apply suggestion from @agoerler
rjayasinghe Nov 27, 2025
5b9016d
Apply suggestion from @schwma
rjayasinghe Nov 27, 2025
bcb4ab3
Apply suggestion from @patricebender
rjayasinghe Nov 27, 2025
846d465
Apply suggestion from @Akatuoro
rjayasinghe Nov 27, 2025
e536412
rephrase first section of @assert docu
rjayasinghe Nov 25, 2025
53cd987
move section about i18n and message keys down to error function
rjayasinghe Nov 27, 2025
caa6f57
Merge remote-tracking branch 'origin/main' into assert-docs
rjayasinghe Nov 28, 2025
45b6781
use smaller code box instead of disfunctional code focus
rjayasinghe Nov 28, 2025
884a35c
remove section about error function
rjayasinghe Nov 28, 2025
fafff8f
apply review comments
rjayasinghe Nov 28, 2025
90a9715
Update guides/providing-services.md
StefanHenke Dec 1, 2025
9cb4a42
Update guides/providing-services.md
StefanHenke Dec 1, 2025
f3148de
incorporate feedback
StefanHenke Dec 1, 2025
60f8d3c
Merge remote-tracking branch 'origin' into assert-docs
StefanHenke Dec 1, 2025
d055d98
:Merge remote-tracking branch 'origin/assert-docs' into assert-docs
StefanHenke Dec 1, 2025
4d4891d
revert ternary comment
StefanHenke Dec 1, 2025
4b0360d
fix code snippets
StefanHenke Dec 2, 2025
b605960
remove parenthesis
StefanHenke Dec 2, 2025
9fef206
Merge remote-tracking branch 'origin/main' into assert-docs
agoerler Dec 11, 2025
dfcdbd7
add disclaimers
agoerler Dec 11, 2025
9824347
Apply suggestions from code review
agoerler Dec 11, 2025
00cc8cc
Apply suggestions from code review
StefanHenke Dec 12, 2025
3cdf60d
fix linting issues
StefanHenke Dec 12, 2025
2e55c00
fix ternary expressions
StefanHenke Dec 12, 2025
9eb51b2
incorporate feedback
StefanHenke Dec 15, 2025
22dfb34
Merge branch 'main' into assert-docs
StefanHenke Dec 15, 2025
9526c32
incorporate latest feedback
StefanHenke Dec 15, 2025
cd4accc
incorporate latest feedback
StefanHenke Dec 15, 2025
278095c
incorporate latest feedback
StefanHenke Dec 15, 2025
aa58ba8
Apply suggestions from code review
renejeglinsky Dec 15, 2025
9e8459d
Merge branch 'main' into assert-docs
danjoa Dec 16, 2025
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
80 changes: 53 additions & 27 deletions guides/providing-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@ The `@assert.target` check constraint relies on database locks to ensure accurat

### `@assert` <Beta/>

Annotate an _element_ with `@assert` to define CXL expressions to be validated _after_ the data has been written to the database. If the validation should fail, the expression will return a String that indicates an error to the runtime, or `null` if the validation passes.
Annotate an _element_ with `@assert` to define CXL expressions to be validated _after_ the data has been written to the database but _before_ it is committed. If the validation should fail, the expression will return a String that indicates an error to the runtime, or `null` if the validation passes.

```cds
entity OrderItems : cuid {
Expand All @@ -965,60 +965,86 @@ entity OrderItems : cuid {

#### Error Messages and Message Targets

If a validation fails, the transaction is rolled back with an exception. If you use [Fiori draft state messages](../advanced/fiori#validating-drafts) the error is persisted. The exception or error targets the annotated element, which is then highlighted on the Fiori UI.
If a validation fails, the transaction is rolled back with an exception. If you use [Fiori draft state messages](../advanced/fiori#validating-drafts) the error is persisted. The error targets the annotated element, which is then highlighted on the Fiori UI.

::: info Error Messages
The error message returned by the CXL expression inside the annotation can be either a static message or a message key to support i18n. If a message key is used, the message is looked up in the message bundle of the service.
[Learn more about localized messages](./i18n){.learn-more}
:::

::: info Multiple Targets
If an assert should target multiple elements you need to annotate all targeted elements.
:::

#### Complex Asserts

An `@assert` annotation may use other elements from the same entity. This annotation checks that the delivery date of an order is after the order date:
::: warning Use complex asserts on service layer
Like other annotations, `@assert` is propagated to projections. If you annotate an element with `@assert` and the condition uses other elements - from the same or an associated entity - you must ensure that these elements are available in all projections to which the annotated element is propagated. Otherwise the CDS model won't compile.

It is therefore recommended to use complex asserts on the highest projection, i.e. on the service layer.
:::

For the examples given in this section, consider the following CDS _domain_ model:

```cds
entity Order : cuid {

@assert: (deliveryDate < orderDate ? 'DELIVERY_BEFORE_ORDER' : null)
items : Integer;
context db {
entity Books : cuid {
title : String;
stock : Integer;
deliveryDate : Date;
orderDate : Date;
}

entity Orders : cuid {
items : Composition of many OrderItems on items.order = $self;
}

entity OrderItems : cuid {
order: Association to Orders;
book : Association to Books;
quantity : Integer;
}
}
```

An `@assert` annotation may use other elements from the same entity. This annotation checks that the delivery date of an order is after the order date:

```cds
service OrderService {
entity Orders as projection on db.Orders;

annotate Orders with {
deliveryDate @assert: (deliveryDate < orderDate ? 'DELIVERY_BEFORE_ORDER' : null); // [!code highlight]
};
}
```
In an `@assert` condition you can also refer to elements of associated entities. The following example ensures that the `quantity` of the ordered book is validated against the actual `stock`. If the stock level is insufficient, a static error message is returned:

```cds
entity OrderItems : cuid {

@assert: (case
when book.stock <= quantity then 'Stock exceeded'
end)
quantity : Integer;
service OrderService {
entity OrderItems as projection on db.OrderItems;

annotate OrderItems with {
quantity @assert: (case // [!code highlight]
when book.stock <= quantity then 'Stock exceeded' // [!code highlight]
end); // [!code highlight]
};
}
```

You can also perform validations based on entities associated via a to-many association. Use an [exists predicate](../cds/cql#exists-predicate) in this case:

```cds
entity Order : cuid {

@assert: (exists items[book.isNotReleased = true]
? 'Some ordered book is not yet released' : null)
items : Integer;
service OrderService {
entity OrdersItems as projection on db.OrderItems;

annotate OrderItems with {
quantity @assert: (case // [!code highlight]
when book.stock <= quantity then 'Stock exceeded' // [!code highlight]
end); // [!code highlight]
};
}
```

Refer to [Expressions as Annotation Values](../cds/cdl.md#expressions-as-annotation-values) for detailed rules on expression syntax.

::: warning Use complex asserts on service layer
Like other annotations, `@assert` is propagated to projections. If you annotate an element with `@assert` and the condition uses other elements - from the same or an associated entity - you must ensure that these elements are avaliable in all projections to which the annotated element is propagated. Otherwise the CDS model won't compile.

It is therefore recommended to use complex asserts on the highest projection, i.e. on the service layer.
:::

#### Multiple Conditions

Use multiple `when` clauses to check multiple conditions with a single `@assert` annotation. Each condition returns its own error message to precisely describe the error:
Expand Down
Loading