Skip to content

Release 2025-07-04 #1954

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

Open
wants to merge 29 commits into
base: cap.cloud.sap
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
e9f2f19
Fix very minor issue in authorization.md (#1929)
qmacro Jun 24, 2025
008b679
Update versions for MTX sidecar
swaldmann Jun 24, 2025
ceb6afe
chore: Update CLI texts (#1933)
github-actions[bot] Jun 25, 2025
775af7a
Review on Java - Validating Drafts (#1917)
renejeglinsky Jun 25, 2025
faa6743
fix (?) the after phase handler sample in messaging topic (#1934)
qmacro Jun 25, 2025
5afed2c
Improve custom streaming docu (#1894)
vkozyura Jun 25, 2025
612a918
Make examples the same order and params (#1705)
nkaputnik Jun 30, 2025
c927898
Document Hierarchy Support on H2 (#1938)
eugene-andreev Jul 1, 2025
5fcd1df
Improve description of srv.send (#1930)
vkozyura Jul 1, 2025
4525c8d
Vector Embeddings: Add example w/ Cloud SDK for AI (#1914)
MattSchur Jul 2, 2025
4890312
chore(deps): update dependency com.sap.cds:cds4j-api to v4.1.0 (#1945)
renovate[bot] Jul 2, 2025
95d0686
chore(deps): update dependency cspell to v9.1.2 (#1932)
renovate[bot] Jul 2, 2025
282c886
chore(deps): update eslint (#1931)
renovate[bot] Jul 2, 2025
fc727d4
docs: Add missing , (#1936)
tklein1801 Jul 2, 2025
de0dc15
use -f to cf install-plugin (#1941)
qmacro Jul 2, 2025
3141000
Point out additional restriction for feature toggles (#1947)
daogrady Jul 3, 2025
3f2c005
Dependency bump
chgeo Jul 3, 2025
80f2b3d
MT Classic: set to not released (#1949)
renejeglinsky Jul 3, 2025
85bddbb
Remove limitation of remote services (#1943)
mofterdinger Jul 3, 2025
51dd226
Use non-beta flag for draftMessages (#1948)
beckermarc Jul 3, 2025
9eff059
docs: Grammar fix in events.md (#1935)
eric-pSAP Jul 3, 2025
9d50620
Fix (?) to shared-db testing in microservices.md (#1937)
qmacro Jul 3, 2025
415698f
chore(deps): update dependency com.sap.cds:cds-services-api to v4.1.0…
renovate[bot] Jul 3, 2025
f7eee25
Java: Views and Projections (#1916)
MattSchur Jul 4, 2025
7eafa3c
Add media properties to Remote OData Documentation (#1950)
vmikhailenko Jul 4, 2025
a3fb188
chore(deps): update dependency @cap-js/cds-types to v0.13.0 (#1953)
renovate[bot] Jul 4, 2025
dca6701
chore(deps): update dependency @cap-js/cds-typer to v0.36.0 (#1952)
renovate[bot] Jul 4, 2025
5a8bcd7
Add description for js rules (#1946)
daogrady Jul 4, 2025
413bb88
switched link
renejeglinsky Jul 4, 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
4 changes: 2 additions & 2 deletions .vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ config.rewrites = rewrites
// Add custom capire info to the theme config
config.themeConfig.capire = {
versions: {
java_services: '4.0.2',
java_cds4j: '4.0.2'
java_services: '4.1.0',
java_cds4j: '4.1.0'
},
gotoLinks: []
}
Expand Down
9 changes: 6 additions & 3 deletions advanced/odata.md
Original file line number Diff line number Diff line change
Expand Up @@ -1111,9 +1111,12 @@ Provide support for hierarchy attribute calculation and navigation, and allow th

- <sup>(1)</sup> Beta feature, API may change

::: warning
Generic implementation is supported on SAP HANA only
:::
Generic implementation is supported on the following databases:

| | SAP HANA | H2 | PostgreSQL | SQLite |
|---|---|---|---|---|
| CAP Java | ✓ | ✓ | | |
| CAP Node.js | ✓ | |✓ |✓ |

:::info
The source elements of the entity defining the recursive parent-child relation are identified by a naming convention or aliases `node_id` and `parent_id`.
Expand Down
132 changes: 82 additions & 50 deletions guides/databases-hana.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
---
status: released
impl-variants: true
---

# Using SAP HANA Cloud for Production

<ImplVariantsHint />

[[toc]]


Expand All @@ -20,52 +17,42 @@ CAP isn't validated with other variants of SAP HANA, like "SAP HANA Database as

## Setup & Configuration

<div class="impl node">

Run this to use SAP HANA Cloud for production:
To use SAP HANA Cloud for production, add a dependency to the _package.json_ for Node.js or to the _pom.xml_ for a CAP Java application:

```sh
::: code-group
```sh [Shell/Bash]
npm add @cap-js/hana
```

::: details Using other SAP HANA drivers...

Package `@cap-js/hana` uses the [`hdb`](https://www.npmjs.com/package/hdb) driver by default. You can override that by running [`npm add @sap/hana-client`](https://www.npmjs.com/package/@sap/hana-client), thereby adding it to your package dependencies, which then takes precedence over the default driver.

:::

::: tip Prefer `cds add`

... as documented in the [deployment guide](deployment/to-cf#_1-sap-hana-database), which also does the equivalent of `npm add @cap-js/hana` but in addition cares for updating `mta.yaml` and other deployment resources.

:::

</div>

<div class="impl java">

To use SAP HANA Cloud, [configure a module](../java/developing-applications/building#standard-modules), which includes the feature `cds-feature-hana`.
For example, add a Maven runtime dependency to the `cds-feature-hana` feature:

```xml
```xml [pom.xml]
<dependency>
<groupId>com.sap.cds</groupId>
<artifactId>cds-feature-hana</artifactId>
<scope>runtime</scope>
</dependency>
```
:::

::: tip
::: details Using other SAP HANA drivers...

The [modules](../java/developing-applications/building#standard-modules) `cds-starter-cloudfoundry` and `cds-starter-k8s` include `cds-feature-hana`.
Package `@cap-js/hana` uses the [`hdb`](https://www.npmjs.com/package/hdb) driver by default. You can override that by running [`npm add @sap/hana-client`](https://www.npmjs.com/package/@sap/hana-client), thereby adding it to your package dependencies, which then takes precedence over the default driver.

:::

The datasource for HANA is then auto-configured based on available service bindings of type *service-manager* and *hana*.
:::details In CAP Java ...
The [modules](../java/developing-applications/building#standard-modules) `cds-starter-cloudfoundry` and `cds-starter-k8s` include `cds-feature-hana`.

The datasource for SAP HANA is then auto-configured based on available service bindings of type *service-manager* and *hana*.

[Learn more about the configuration of an SAP HANA Cloud Database](../java/cqn-services/persistence-services#sap-hana){ .learn-more}
:::

::: tip Prefer `cds add`

... as documented in the [deployment guide](deployment/to-cf#_1-sap-hana-database), which also does the equivalent of `npm add @cap-js/hana` but in addition cares for updating `mta.yaml` and other deployment resources.

:::

</div>



Expand Down Expand Up @@ -266,41 +253,86 @@ The HANA Service provides dedicated support for native SAP HANA features as foll

### Vector Embeddings { #vector-embeddings }

Vector embeddings are numerical representations that capture important features and semantics of unstructured data - such as text, images, or audio. This representation makes vector embeddings of similar data have high similarity and low distance to each other. These properties of vector embeddings facilitate tasks like similarity search, anomaly detection, recommendations and Retrieval Augmented Generation (RAG). Vector embeddings from a vector datastore such as the [SAP HANA Cloud Vector Engine](https://community.sap.com/t5/technology-blogs-by-sap/sap-hana-cloud-s-vector-engine-announcement/ba-p/13577010) can help get better generative AI (GenAI) results. This is achieved when the embeddings are used as context to the large language models (LLMs) prompts.
Vector embeddings let you add semantic search, recommendations, and generative AI features to your CAP application. Embeddings are numeric arrays that represent the meaning of unstructured data (text, images, etc.), making it possible to compare and search for items that are semantically related to each other or a user query.

Typically vector embeddings are computed using an **embedding model**. The embedding model is specifically designed to capture important features and semantics of a specific type of data, it also determines the dimensionality of the vector embedding space. Unified consumption of embedding models and LLMs across different vendors and open source models is provided via the [SAP Generative AI Hub](https://community.sap.com/t5/technology-blogs-by-sap/how-sap-s-generative-ai-hub-facilitates-embedded-trustworthy-and-reliable/ba-p/13596153).
#### Choose an Embedding Model

In CAP, vector embeddings are stored in elements of type [cds.Vector](../cds/types):
Choose an embedding model that fits your use case and data (for example english or multilingual text). The model determines the number of dimensions of the resulting output vector. Check the documentation of the respective embedding model for details.

```cds
entity Books : cuid { // [!code focus]
title : String(111);
description : LargeString; // [!code focus]
embedding : Vector(1536); // vector space w/ 1536 dimensions // [!code focus]
} // [!code focus]
Use the [SAP Generative AI Hub](https://community.sap.com/t5/technology-blogs-by-sap/how-sap-s-generative-ai-hub-facilitates-embedded-trustworthy-and-reliable/ba-p/13596153) for unified consumption of embedding models and LLMs across different vendors and open source models. Check for available models on the [SAP AI Launchpad](https://help.sap.com/docs/ai-launchpad/sap-ai-launchpad-user-guide/models-and-scenarios-in-generative-ai-hub-fef463b24bff4f44a33e98bb1e4f3148#models).

#### Add Embeddings to Your CDS Model
Use the `cds.Vector` type in your CDS model to store embeddings on SAP HANA Cloud. Set the dimension to match your embedding model (for example, 1536 embedding dimensions for OpenAI *text-embedding-3-small*).

```cds
entity Books : cuid {
title : String(111);
description : LargeString;
embedding : Vector(1536); // adjust dimensions to embedding model
}
```

#### Generate Embeddings
Use an embedding model to convert your data (for example, book descriptions) into vectors. The [SAP Cloud SDK for AI](https://sap.github.io/ai-sdk/) makes it easy to call SAP AI Core services to generate these embeddings.

:::details Example using SAP Cloud SDK for AI
```Java
var aiClient = OpenAiClient.forModel(OpenAiModel.TEXT_EMBEDDING_3_SMALL);
var response = aiClient.embedding(
new OpenAiEmbeddingRequest(List.of(book.getDescription())));
book.setEmbedding(CdsVector.of(response.getEmbeddingVectors().get(0)));
```
:::

At runtime, you can compute the similarity and distance of vectors in the SAP HANA vector store using the `cosineSimilarity` and `l2Distance` (Euclidean distance) functions in queries:
#### Query for Similarity
At runtime, use SAP HANA's built-in vector functions to search for similar items. For example, find books with embeddings similar to a user question:

::: code-group
```js [Node.js]
let embedding; // vector embedding as string '[0.3,0.7,0.1,...]';
```Java [Java]
// Compute embedding for user question
var request = new OpenAiEmbeddingRequest(List.of("How to use vector embeddings in CAP?"));
CdsVector userQuestion = CdsVector.of(
aiClient.embedding(request).getEmbeddingVectors().get(0));
// Compute similarity between user question and book embeddings
var similarity = CQL.cosineSimilarity( // computed on SAP HANA
CQL.get(Books.EMBEDDING), userQuestion);
// Find Books related to user question ordered by similarity
hana.run(Select.from(BOOKS).limit(10)
.columns(b -> b.ID(), b -> b.title(),
b -> similarity.as("similarity"))
.orderBy(b -> b.get("similarity").desc()));
```

```js [Node.js]
const response = await new AzureOpenAiEmbeddingClient(
'text-embedding-3-small'
).run({
input: 'How to use vector embeddings in CAP?'
});
const questionEmbedding = response.getEmbedding();
let similarBooks = await SELECT.from('Books')
.where`cosine_similarity(embedding, to_real_vector(${embedding})) > 0.9`
.where`cosine_similarity(embedding, to_real_vector(${questionEmbedding})) > 0.9`;
```

```java [Java]
// Vector embedding of text, for example, from SAP GenAI Hub or via LangChain4j
float[] embedding = embeddingModel.embed(bookDescription).content().vector();
:::

Result similarBooks = service.run(Select.from(BOOKS).where(b ->
CQL.cosineSimilarity(b.embedding(), CQL.vector(embedding)).gt(0.9)));
```
:::tip
Store embeddings when you create or update your data. Regenerate embeddings if you change your embedding model.
:::

:::tip SAP Cloud SDK for AI
Use the [SAP Cloud SDK for AI](https://sap.github.io/ai-sdk/) for unified access to embedding models and large language models (LLMs) from [SAP AI Core](https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/what-is-sap-ai-core).
:::


[Learn more about the SAP Cloud SDK for AI (Java)](https://sap.github.io/ai-sdk/docs/java/getting-started) {.learn-more}

[Learn more about Vector Embeddings in CAP Java](../java/cds-data#vector-embeddings) {.learn-more}

[Learn more about the SAP Cloud SDK for AI (JavaScript)](https://sap.github.io/ai-sdk/docs/js/getting-started) {.learn-more}




### Geospatial Functions

Expand Down
4 changes: 2 additions & 2 deletions guides/deployment/microservices.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ cd shared-db
```

```sh
cds db -2 sql
cds compile db -2 sql
```
```sh
cds db -2 hana
cds compile db -2 hana
```

```sh
Expand Down
4 changes: 2 additions & 2 deletions guides/deployment/to-cf.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ npm i @sap/cds #> if necessary

```sh
cf add-plugin-repo CF-Community https://plugins.cloudfoundry.org
cf install-plugin multiapps
cf install-plugin html5-plugin
cf install-plugin -f multiapps
cf install-plugin -f html5-plugin
```

## Prepare for Production {#prepare-for-production}
Expand Down
14 changes: 4 additions & 10 deletions guides/extensibility/feature-toggles.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ This feature extends corresponding SAP Fiori annotations to display already exis
Note the following limitations for `.cds` files in features:

- no `.cds` files in subfolders, for example, `fts/isbn/sub/file.cds`
- no `using` dependencies between features
- no `using` dependencies between features, any entity, service or type that you refer to or extend needs to be part of the base model
- further limitations re `extend aspect` → to be documented
:::

Expand Down Expand Up @@ -255,18 +255,12 @@ An MTX sidecar is a standard, yet minimalistic Node.js CAP project. By default i
{
"name": "mtx-sidecar", "version": "0.0.0",
"dependencies": {
"@sap/cds": "^7",
"@sap/cds-mtxs": "^1",
"@sap/cds": "^9",
"@sap/cds-mtxs": "^3",
"express": "^4"
},
"cds": {
"requires": {
"cds.xt.ModelProviderService": "in-sidecar"
},
"[development]": {
"requires": { "auth": "dummy" },
"server": { "port": 4005 }
}
"profile": "mtx-sidecar"
}
}
```
Expand Down
2 changes: 1 addition & 1 deletion guides/messaging/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ Find the code to emit events in *[@capire/reviews/srv/reviews-service.js](https:
class ReviewsService extends cds.ApplicationService { async init() {

// Emit a `reviewed` event whenever a subject's avg rating changes
this.after (['CREATE','UPDATE','DELETE'], 'Reviews', (req) => {
this.after (['CREATE','UPDATE','DELETE'], 'Reviews', (_, req) => {
let { subject } = req.data, count, rating //= ...
return this.emit ('reviewed', { subject, count, rating })
})
Expand Down
8 changes: 4 additions & 4 deletions guides/multitenancy/mtxs.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,14 @@ An MTX sidecar is a standard, yet minimal Node.js CAP project. By default it's a
{
"name": "bookshop-mtx", "version": "0.0.0",
"dependencies": {
"@sap/cds": "^7",
"@sap/cds-hana": "^2",
"@sap/cds-mtxs": "^1",
"@sap/cds": "^9",
"@cap-js/hana": "^2",
"@sap/cds-mtxs": "^3",
"@sap/xssec": "^4",
"express": "^4"
},
"devDependencies": {
"@cap-js/sqlite": "^1"
"@cap-js/sqlite": "^2"
},
"scripts": {
"start": "cds-serve"
Expand Down
43 changes: 35 additions & 8 deletions guides/providing-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -1109,9 +1109,9 @@ module.exports = class Sue extends cds.Service {
```js
GET .../sue/sum(x=1,y=2) // unbound function
GET .../sue/stock(id=2) // unbound function
POST .../sue/add {"x":1,"to":2} // unbound action
POST .../sue/add {"x":11,"to":2} // unbound action
GET .../sue/Foo(2)/Sue.getStock() // bound function
POST .../sue/Foo(2)/Sue.order {"x":1} // bound action
POST .../sue/Foo(2)/Sue.order {"x":3} // bound action
```

> Note: You always need to add the `()` for functions, even if no arguments are required. The OData standard specifies that bound actions/functions need to be prefixed with the service's name. In the previous example, entity `Foo` has a bound action `order`. That action must be called via `/Foo(2)/Sue.order` instead of simply `/Foo(2)/order`.
Expand All @@ -1123,18 +1123,45 @@ POST .../sue/Foo(2)/Sue.order {"x":1} // bound action
<br>


**Programmatic** usage via **generic APIs** would look like this for Node.js:
**Programmatic** usage via **generic APIs** for Node.js:

For unbound actions and functions:

```ts
async function srv.send (
event : string | { event, data?, headers?: object },
data? : object | any
)
return : result of this.dispatch(req)
```

For bound actions and functions:

```ts
async function srv.send (
event : string | { event, entity, data?, params?: array of object, headers?: object },
entity : string,
data? : object | any
)
return : result of this.dispatch(req)
```

- `event` is a name of a custom action or function
- `entity` is a name of an entity
- `params` are keys of the entity instance

Programmatic usage would look like this for Node.js:

```js
const srv = await cds.connect.to('Sue')
// unbound actions/functions
await srv.send('sum',{x:1,y:2})
await srv.send('add',{x:11,to:2})
await srv.send('stock',{id:2})
// bound actions/functions
await srv.send('add',{x:11,to:2})
// actions/functions bound to collection
await srv.send('getStock','Foo',{id:2})
//for passing the params property, use this syntax
await srv.send({ event: 'order', entity: 'Foo', data: {x:3}, params: [2]})
// for actions/functions bound to entity instance, use this syntax
await srv.send({ event: 'order', entity: 'Foo', data: {x:3}, params: [{id:2}]})
```

> Note: Always pass the target entity name as second argument for bound actions/functions.
Expand All @@ -1147,8 +1174,8 @@ POST .../sue/Foo(2)/Sue.order {"x":1} // bound action
const srv = await cds.connect.to(Sue)
// unbound actions/functions
srv.sum(1,2)
srv.add(11,2)
srv.stock(2)
srv.add(11,2)
// bound actions/functions
srv.getStock('Foo',2)
srv.order('Foo',2,3)
Expand Down
2 changes: 1 addition & 1 deletion guides/security/authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ service SomeService {

#### Events to Auto-Exposed Entities { #events-and-auto-expose}

In general, entities can be exposed in services in different ways: it can be **explicitly exposed** by the modeler (for example, by a projection), or it can be **auto-exposed** by the CDS compiler due to some reason.
In general, entities can be exposed in services in different ways: they can be **explicitly exposed** by the modeler (for example, by a projection), or they can be **auto-exposed** by the CDS compiler due to some reason.
Access to auto-exposed entities needs to be controlled in a specific way. Consider the following example:

```cds
Expand Down
Loading