-|
+ |
BETWEEN
|
From e9ca1dc009b572f0da657e8e530d7114823a16c8 Mon Sep 17 00:00:00 2001
From: Markus Ofterdinger
Date: Wed, 4 Jun 2025 07:34:57 +0200
Subject: [PATCH 134/140] Update versions.md (#1893)
---
java/versions.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/java/versions.md b/java/versions.md
index e3186ef962..25073edc17 100644
--- a/java/versions.md
+++ b/java/versions.md
@@ -80,13 +80,14 @@ The following table lists these minimum versions for various common dependencies
| Dependency | Minimum Version | Recommended Version |
| --- | --- | --- |
| JDK | 17 | 21 |
-| Maven | 3.6.3 | 3.9.8 |
+| Maven | 3.6.3 | 3.9.9 |
| @sap/cds-dk | 7 | latest |
| @sap/cds-compiler | 4 | latest |
| Spring Boot | 3.0 | latest |
| XSUAA | 3.0 | latest |
| SAP Cloud SDK | 5.9 | latest |
| Java Logging | 3.7 | latest |
+| Node.js | 18 | 20 |
### Consistent Versions
From 2ba9905d0a7c9ec142064c5c142bcab86165652b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrian=20G=C3=B6rler?=
Date: Wed, 4 Jun 2025 07:47:16 +0200
Subject: [PATCH 135/140] Document cds.Map type (#1895)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---
java/cds-data.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/java/cds-data.md b/java/cds-data.md
index 8b6f7538e5..a897eea7ae 100644
--- a/java/cds-data.md
+++ b/java/cds-data.md
@@ -43,6 +43,7 @@ The [predefined CDS types](../cds/types) are mapped to Java types and as follows
| `cds.Binary` | `byte[]` | |
| `cds.LargeBinary` | `byte[]` | `java.io.InputStream` (1) if annotated with `@Core.MediaType` |
| `cds.Vector` | `com.sap.cds.CdsVector` | for [vector embeddings](#vector-embeddings) |
+| `cds.Map` | `java.util.Map` | for arbitrary [structured data](#structured-data)(2) |
### SAP HANA-Specific Data Types
@@ -62,6 +63,7 @@ To facilitate using legacy CDS models, the following [SAP HANA-specific data typ
> (1) Although the API to handle large objects is the same for every database, the streaming feature, however, is supported (and tested) in **SAP HANA**, **PostgreSQL**, and **H2**. See section [Database Support in Java](./cqn-services/persistence-services#database-support) for more details on database support and limitations.
+> (2) Serialized as JSON to a CLOB column or JSONB column (on Postgres)
::: warning
The framework isn't responsible for closing the stream when writing to the database. You decide when the stream is to be closed. If you forget to close the stream, the open stream can lead to a memory leak.
From 55a4724d7eee8444477355e644183b5a57ba9c86 Mon Sep 17 00:00:00 2001
From: Rene Jeglinsky
Date: Wed, 4 Jun 2025 14:06:11 +0200
Subject: [PATCH 136/140] edit
---
guides/deployment/microservices.md | 51 ++++++++++++++++--------------
1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/guides/deployment/microservices.md b/guides/deployment/microservices.md
index df9cfd6e7f..12e87c5c80 100644
--- a/guides/deployment/microservices.md
+++ b/guides/deployment/microservices.md
@@ -19,13 +19,13 @@ Assumed we want to create a composite application consisting of two or more micr
- https://github.com/capire/reviews
- https://github.com/capire/orders
-With some additional repos, used as dependencies in the same manner, like:
+With some additional repositories, used as dependencies in the same manner, like:
- https://github.com/capire/common
- https://github.com/capire/bookshop
- https://github.com/capire/data-viewer
-This guide describes a way to manage development and deployment via *[monorepos](https://en.wikipedia.org/wiki/Monorepo)* using *[NPM workspaces](https://docs.npmjs.com/cli/using-npm/workspaces)* and *[git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)* techniques...
+This guide describes a way to manage development and deployment via *[monorepos](https://en.wikipedia.org/wiki/Monorepo)* using *[NPM workspaces](https://docs.npmjs.com/cli/using-npm/workspaces)* and *[git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules)* techniques.
1. Create a new monorepo root directory using *NPM workspaces*:
@@ -98,7 +98,10 @@ When one of the projects is cloned in isolation, it's still possible to fetch de
## Using a Shared Database
-If you have multiple CAP applications relying on the same domain model or want to split up a monolithic CAP application **on the service level only while still sharing the underlying database layer**, you can deploy your model to a single database and then share it across applications.
+You can deploy your model to a single database and then share it across applications, if you have one of the following scenarios:
+
+- multiple CAP applications relying on the same domain model
+- a monolithic CAP application that you want to split up **on the service level only, while still sharing the underlying database layer**
In the following steps, we create an additional project to easily collect the relevant models from these projects, and act as a vehicle to deploy these models to SAP HANA in a controlled way.
@@ -185,9 +188,9 @@ The project structure used here is as follows:
ββ package.json
```
-The `shared-db` module is simply another CAP project, with only db content. The dependencies are installed via NPM, so it's still possible to install via an NPM registry if used outside of the monorepo setup.
+The `shared-db` module is simply another CAP project, with only database content. The dependencies are installed via NPM, so it's still possible to install via an NPM registry if used outside of the monorepo setup.
-The db model could also be collected on root level instead of creating a separate `shared-db` module. When collecting on root level, the `cds build --ws` option can be used to collect the models of all NPM workspaces.
+The database model could also be collected on root level instead of creating a separate `shared-db` module. When collecting on root level, the `cds build --ws` option can be used to collect the models of all NPM workspaces.
:::
@@ -658,7 +661,7 @@ modules:
```
:::
-The _xs-app.json_ file describes how to forward incoming request to the API endpoint / OData services and is located in the app/router folder. Each exposed CAP Service endpoint needs to be directed to the corresponding application which is providing this CAP service.
+The _xs-app.json_ file describes how to forward incoming request to the API endpoint / OData services and is located in the _.deploy/app-router_ folder. Each exposed CAP Service endpoint needs to be directed to the corresponding application which is providing this CAP service.
::: code-group
```json [.deploy/app-router/xs-app.json]
@@ -792,13 +795,13 @@ You can then navigate to this url and the corresponding apps
```
-## Deployment as separate mta
+## Deployment as Separate MTA
-This is an alternative to the all-in-one deployment. Assume the applications each already have their own mta.yaml. For example by running `cds add mta` in the `reviews`, `orders` and `bookstore` folder.
+This is an alternative to the all-in-one deployment. Assume the applications each already have their own _mta.yaml_. For example by running `cds add mta` in the _reviews_, _orders_ and _bookstore_ folder.
### Database
-We can add the [previously created](#using-a-shared-database) `shared-db` project as its own mta deployment:
+We can add the [previously created](#using-a-shared-database) `shared-db` project as its own MTA deployment:
::: code-group
```sh [shared-db/]
@@ -877,7 +880,7 @@ resources:
The only thing left to care about is to ensure all 3+1 projects are bound and connected to the same database at deployment, subscription, and runtime.
-Configure the mta.yaml of the other apps to bind to the existing shared database, for example, in the reviews module:
+Configure the _mta.yaml_ of the other apps to bind to the existing shared database, for example, in the reviews module:
```yaml [reviews/mta.yaml]
...
@@ -907,7 +910,7 @@ resources:
#### Subsequent updates
-Whenever one of the projects has changes affecting the database, the database artifacts need to be deployed prior to the application deployment. With a single `mta.yaml`, this is handled in the scope of the mta deployment. When using multiple deployment units, ensure to first deploy the `shared-db` project before deploying the others.
+Whenever one of the projects has changes affecting the database, the database artifacts need to be deployed prior to the application deployment. With a single _mta.yaml_, this is handled in the scope of the MTA deployment. When using multiple deployment units, ensure to first deploy the `shared-db` project before deploying the others.
## Late-Cut Microservices
@@ -932,7 +935,7 @@ Instead of just choosing between a monolith and microservices, these aspects can
Since each cut not only has benefits, but also drawbacks, it's important to choose which benefits actually help the overall product and which drawbacks can be accepted.
-
+
### A Late Cut
@@ -941,16 +944,16 @@ When developing a product, it may initially not be apparent where the boundaries
Keeping this in mind, an app can be developed as a modular application with use case specific CAP services.
It can first be deployed as a [monolith / modulith](#monolith-or-microservice). Once the boundaries are clear, it can then be split into multiple applications.
-Generally, the semantic separation and structure can be enforced using modules. The deployment configuration is then an independent step on top. In this way, the same application can be deployed as a monolith, as microservices with shared db, as true microservices, or a combination of these, just via configuration change.
+Generally, the semantic separation and structure can be enforced using modules. The deployment configuration is then an independent step on top. In this way, the same application can be deployed as a monolith, as microservices with a shared database, as true microservices, or a combination of these, just via configuration change.

-### Best Practices
+### Best Practices {.good}
* Prefer a late cut
* Stay flexible in where to cut
-* Prefer staying loosely coupled β for example, ReviewsService β reviewed events β UPDATE avg ratings
-* Leverage db-level integration selectively β Prefer referring to (public) service entities, not (private) db entities
+* Prefer staying loosely coupled β for example, ReviewsService β reviewed events β UPDATE average ratings
+* Leverage database-level integration selectively β Prefer referring to (public) service entities, not (private) database entities
## Appendix
@@ -958,27 +961,27 @@ Generally, the semantic separation and structure can be enforced using modules.
A monolith is a single deployment unit with a single application. This is very convenient, because every part of the app is accessible in memory.
-
+
A modulith, even though the app is separated into multiple CAP services inside multiple modules, can still be deployed as a single monolithic application.
This combines the benefit of a clear structure and distributed development while keeping a simple deployment.
-
+
True microservices each consist of their own deployment unit with their own application and their own database.
Meaning that they're truly independent of each other. And it works well if they are actually independent.
-
+
What was mentioned earlier is a simplified view. In an actual microservice deployment, there are typically shared service instances and wiring needs to be provided so that apps can talk to each other, directly or via events.
If the microservices are not cut well, the communication overhead leads to high performance losses and often the need for data replication or caching.
-
+
### Application Instances
-Having only a single virtual machine or container, the application can only be scaled vertically by increasing the cpu and memory resources. This typically has an upper limit and requires a restart when scaling.
+Having only a single virtual machine or container, the application can only be scaled vertically by increasing the CPU and memory resources. This typically has an upper limit and requires a restart when scaling.
To improve scalability, we can start multiple instances of the same application.
@@ -1024,13 +1027,13 @@ Drawbacks:
#### Resource Separation
One part of an application may do highly critical background processing, while another handles incoming requests.
-The incoming requests take cpu cycles and consume memory, which should rather be used for the background processing.
+The incoming requests take CPU cycles and consume memory, which should rather be used for the background processing.
To make sure that there are always enough resources for specific tasks, they can be split into their own app.
#### Independent Scaling
Similar to resource separation, different parts of the app may have different requirements and profiles for scaling.
-For some parts, a 100% cpu utilization over an extended period is accepted for efficiency, while request handling apps need spare resources to handle user requests with low latency.
+For some parts, a 100% CPU utilization over an extended period is accepted for efficiency, while request handling apps need spare resources to handle user requests with low latency.
#### Fault Tolerance
@@ -1055,7 +1058,7 @@ Drawbacks:
- Coordination between deployment units for updates with dependencies
- Configuration wiring to connect systems across deployment units
-
+
With a single deployment unit, when a fix for one part needs to be deployed, the risk of redeploying the rest of the application needs to be considered.
From 8da86c89f8121e2c7c3ddc24bd0dc6dd8e63e1b9 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Wed, 4 Jun 2025 15:13:43 +0200
Subject: [PATCH 137/140] chore: Update CLI texts (#1896)
Updates the output of cds CLI texts to the latest version.
Co-authored-by: chgeo <7470719+chgeo@users.noreply.github.com>
---
tools/assets/help/cds-compile.out.md | 2 +-
tools/assets/help/cds-debug.out.md | 4 ++++
tools/assets/help/cds-help.out.md | 2 ++
tools/assets/help/cds-init.out.md | 2 +-
tools/assets/help/cds-version-md.out.md | 20 +++++++++-----------
tools/assets/help/cds-version.out.md | 20 +++++++++-----------
6 files changed, 26 insertions(+), 24 deletions(-)
diff --git a/tools/assets/help/cds-compile.out.md b/tools/assets/help/cds-compile.out.md
index 2479f58c0c..8de919a7d4 100644
--- a/tools/assets/help/cds-compile.out.md
+++ b/tools/assets/help/cds-compile.out.md
@@ -18,7 +18,7 @@
- json, yml
- edm, edmx, edmx-v2, edmx-v4, edmx-w4, edmx-x4
- - sql, hdbcds, hdbtable, hana
+ - sql, hana, hdbtable
- cdl
- xsuaa
- openapi
diff --git a/tools/assets/help/cds-debug.out.md b/tools/assets/help/cds-debug.out.md
index 1b861de222..17a16a6bbb 100644
--- a/tools/assets/help/cds-debug.out.md
+++ b/tools/assets/help/cds-debug.out.md
@@ -25,6 +25,10 @@
the debug port (default: '9229' for Node.js, '8000' for Java)
+ -f | --force
+
+ if necessary, automatically enable ssh for the app and restart it
+
EXAMPLES
cds debug
cds debug bookshop-srv --port 8001
diff --git a/tools/assets/help/cds-help.out.md b/tools/assets/help/cds-help.out.md
index 215581b595..e3c65240ac 100644
--- a/tools/assets/help/cds-help.out.md
+++ b/tools/assets/help/cds-help.out.md
@@ -22,6 +22,8 @@
e | env inspect effective configuration
b | build prepare for deployment
d | deploy deploy to databases or cloud
+ | up build and deploy your application
+ | debug debug your application
| subscribe subscribe a tenant to a multitenant SaaS app
| unsubscribe unsubscribe a tenant from a multitenant SaaS app
l | login login to extensible multitenant SaaS app
diff --git a/tools/assets/help/cds-init.out.md b/tools/assets/help/cds-init.out.md
index 6d9a1db73f..64538bdefd 100644
--- a/tools/assets/help/cds-init.out.md
+++ b/tools/assets/help/cds-init.out.md
@@ -84,7 +84,7 @@
cds init bookshop --java
cds init bookshop --add hana
cds init bookshop --add multitenancy,mta
- cds init --java --java:mvn groupId=myGroup,artifactId=newId,package=my.company
+ cds init --java --java:mvn DgroupId=myGroup,DartifactId=newId,Dpackage=my.company
SEE ALSO
cds add - to augment your projects later on
diff --git a/tools/assets/help/cds-version-md.out.md b/tools/assets/help/cds-version-md.out.md
index 7f707e5ac0..5a0c0b19a8 100644
--- a/tools/assets/help/cds-version-md.out.md
+++ b/tools/assets/help/cds-version-md.out.md
@@ -6,15 +6,13 @@
| ---------------------- | --------------------------------------- |
| @cap-js/asyncapi | 1.0.3 |
| @cap-js/cds-types | 0.10.0 |
-| @cap-js/db-service | 1.20.1 |
-| @cap-js/openapi | 1.2.2 |
-| @cap-js/sqlite | 1.11.0 |
-| @sap/cds | 8.9.4 |
-| @sap/cds-compiler | 5.9.4 |
-| @sap/cds-dk (global) | 8.9.4 |
-| @sap/cds-fiori | 1.4.1 |
-| @sap/cds-foss | 5.0.1 |
-| @sap/cds-mtxs | 2.7.2 |
-| @sap/eslint-plugin-cds | 3.2.0 |
-| Node.js | v20.19.1 |
+| @cap-js/db-service | 2.0.1 |
+| @cap-js/openapi | 1.2.3 |
+| @cap-js/sqlite | 2.0.1 |
+| @sap/cds | 9.0.2 |
+| @sap/cds-compiler | 6.0.10 |
+| @sap/cds-dk (global) | 9.0.4 |
+| @sap/cds-fiori | 2.0.1 |
+| @sap/cds-mtxs | 3.0.1 |
+| Node.js | v20.19.2 |
diff --git a/tools/assets/help/cds-version.out.md b/tools/assets/help/cds-version.out.md
index 627791499e..816f6d0f36 100644
--- a/tools/assets/help/cds-version.out.md
+++ b/tools/assets/help/cds-version.out.md
@@ -4,16 +4,14 @@
@cap-js/asyncapi: 1.0.3
@cap-js/cds-types: 0.10.0
-@cap-js/db-service: 1.20.1
-@cap-js/openapi: 1.2.2
-@cap-js/sqlite: 1.11.0
-@sap/cds: 8.9.4
-@sap/cds-compiler: 5.9.4
-@sap/cds-dk (global): 8.9.4
-@sap/cds-fiori: 1.4.1
-@sap/cds-foss: 5.0.1
-@sap/cds-mtxs: 2.7.2
-@sap/eslint-plugin-cds: 3.2.0
-Node.js: v20.19.1
+@cap-js/db-service: 2.0.1
+@cap-js/openapi: 1.2.3
+@cap-js/sqlite: 2.0.1
+@sap/cds: 9.0.2
+@sap/cds-compiler: 6.0.10
+@sap/cds-dk (global): 9.0.4
+@sap/cds-fiori: 2.0.1
+@sap/cds-mtxs: 3.0.1
+Node.js: v20.19.2
your-project: 1.0.0
From 0f4d43ff5982b29ced22358c194898c131f16e52 Mon Sep 17 00:00:00 2001
From: Daniel Hutzel
Date: Wed, 4 Jun 2025 18:42:29 +0200
Subject: [PATCH 138/140] fix links (#1898)
---
node.js/cds-plugins.md | 2 +-
node.js/cds-test.md | 4 ++--
node.js/queue.md | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/node.js/cds-plugins.md b/node.js/cds-plugins.md
index d26ea6f68a..445b456c32 100644
--- a/node.js/cds-plugins.md
+++ b/node.js/cds-plugins.md
@@ -128,4 +128,4 @@ Currently, the following schema contribution points are supported:
#### Usage In a CAP Project
-{.ignore-dark style="width: 688px"}
+{.ignore-dark style="width: 688px"}
diff --git a/node.js/cds-test.md b/node.js/cds-test.md
index 27c3b8bd40..973c9f3da6 100644
--- a/node.js/cds-test.md
+++ b/node.js/cds-test.md
@@ -89,7 +89,7 @@ await POST (`/browse/submitOrder`, { book: 201, quantity: 5 })
#### Authenticated Endpoints
-`cds.test()` uses the standard authentication strategy in development mode, which is the [mocked authentication](../node.js/authentication#mocked). This also includes the usage of [pre-definded mock users](../node.js/authentication#mock-users)
+`cds.test()` uses the standard authentication strategy in development mode, which is the [mocked authentication](./authentication#mocked). This also includes the usage of [pre-definded mock users](./authentication#mock-users)
You can set the user for an authenticated request like this:
@@ -106,7 +106,7 @@ Authorization: Basic alice:
```
:::
-[Learn how to explicitly configure mock users in your _package.json_ file.](../node.js/authentication#mocked){.learn-more}
+[Learn how to explicitly configure mock users in your _package.json_ file.](./authentication#mocked){.learn-more}
### Using Jest or Mocha
diff --git a/node.js/queue.md b/node.js/queue.md
index 5db2026446..dc94b1ccd8 100644
--- a/node.js/queue.md
+++ b/node.js/queue.md
@@ -357,4 +357,4 @@ Add the model path accordingly:
}
```
-Note that model configuration isn't required for CAP projects using the [standard project layout](../get-started/#project-structure) with `db`, `srv`, and `app` folders. In this case, you can delete the entire `model` configuration.
+Note that model configuration isn't required for CAP projects using the [standard project layout](../get-started/index.md#project-structure) with `db`, `srv`, and `app` folders. In this case, you can delete the entire `model` configuration.
From 876a531b3663d10f6297c7364f425c40f58c1830 Mon Sep 17 00:00:00 2001
From: Daniel Hutzel
Date: Wed, 4 Jun 2025 18:43:13 +0200
Subject: [PATCH 139/140] Documented cds.ql() function
---
node.js/cds-ql.md | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/node.js/cds-ql.md b/node.js/cds-ql.md
index 5667cfc3dd..725c8cb9ff 100644
--- a/node.js/cds-ql.md
+++ b/node.js/cds-ql.md
@@ -310,6 +310,32 @@ await cds.ql`SELECT from Authors {
+## cds.ql() {.method}
+
+Use the `cds.ql()` method to construct instances of [`cds.Query`](#class-cds-ql-query) from these inputs:
+
+- tagged template strings (SELECT only)
+- normal strings (SELECT only)
+- plain CQN objects
+
+For example:
+
+```js
+let q = cds.ql ({ SELECT: { from: {ref:[ Books.name ]} }})
+let q = cds.ql (`SELECT from Books { ID, title }`)
+let q = cds.ql `SELECT from ${Books} { ID, title }`
+q instanceof cds.ql.Query //> true
+```
+
+If the input is already a `cds.Query` instance, it is returned unchanged:
+
+```js
+let q1 = cds.ql `SELECT from Books`
+let q2 = cds.ql (q1)
+q1 === q2 //> true
+```
+
+
## cds.ql. Query {#class-cds-ql-query .class}
Instances of `cds.Query` capture queries at runtime. Subclasses provide [fluent APIs](#constructing-queries) to construct queries as highlighted below.
From 97c12aea47262b375f1d22e750fdd033b82a2302 Mon Sep 17 00:00:00 2001
From: Daniel Hutzel
Date: Wed, 4 Jun 2025 19:04:14 +0200
Subject: [PATCH 140/140] Restructured content in cds.connect docs
---
node.js/cds-connect.md | 314 +++++++++++++++++------------------------
1 file changed, 129 insertions(+), 185 deletions(-)
diff --git a/node.js/cds-connect.md b/node.js/cds-connect.md
index e1c3062e94..26b1147e09 100644
--- a/node.js/cds-connect.md
+++ b/node.js/cds-connect.md
@@ -13,15 +13,72 @@ The latter include **database** services. In all cases use `cds.connect` to conn
[[toc]]
+## Connecting to Required Services { #cds-connect-to }
+
+
+
+### cds. connect.to () {.method}
+
+Use `cds.connect.to()` to connect to services configured in a project's `cds.requires` configuration.
+
+```js
+const ReviewsService = await cds.connect.to('ReviewsService')
+```
+
+The method returns a _Promise_ resolving to a _[Service](../cds/cdl#services)_ instance which acts as a client proxy to the service's API, allowing you to call its methods and access its data using common [`cds.Service`](core-services#consuming-services) methods, e.g.:
+
+```js
+let reviews = await ReviewsService.read ('Reviews')
+```
+
+
+**Arguments** are as follows:
+
+```ts:no-line-numbers
+async function cds.connect.to (
+ name? : string, // reference to an entry in `cds.requires` config
+ options? : {
+ kind : string // reference to a preset in `cds.requires.kinds` config
+ impl : string // module name of the implementation
+ }
+) : Promise
+```
+
+Argument `name` is used to look up connect options from [configured services](#cds-env-requires), which are defined in the `cds.requires` section of your _package.json_ or _.cdsrc.json_ or _.yaml_ files.
+
+Argument `options` also allows to pass additional options such as `credentials` programmatically, and thus create services without configurations and [service bindings](#service-bindings), for example, you could connect to a local SQLite database in your tests like this:
+
+```js
+const db2 = await cds.connect.to ({
+ kind: 'sqlite', credentials: { url: 'db2.sqlite' }
+})
+```
+
+
+### cds. services {#cds-connect-caching .property}
+
+When connecting to a service using `cds.connect.to()`, the service instance is cached in [`cds.services`](cds-facade#cds-services) under the service name. This means that subsequent calls to `cds.connect.to()` with the same service name will all return the same instance. As services constructed by [`cds.serve`](cds-serve#cds-serve) are registered with [`cds.services`](cds-facade#cds-services) as well, a connect finds and returns them as local service connections.
+
+You can also access cached service instance like this:
+
+```js
+const { ReviewsService } = cds.services
+```
+
+> Note: If _ad-hoc_ options are provided, the instance is not cached.
+
## Configuring Required Services {#cds-env-requires }
-To configure required remote services in Node.js, simply add respective entries to the `cds.requires` sections in your _package.json_ or in _.cdsrc.json_ (omitting the `cds.` prefix). These configurations are constructed as follows:
+To configure required remote services in Node.js, simply add respective entries to the `cds.requires` sections in your _package.json_ or in _.cdsrc.json_ or _.yaml_. These configurations are constructed as follows:
-```json
-"cds": {
+::: code-group
+
+```json [package.json]
+{"cds":{
"requires": {
+ "db": { "kind": "sqlite", "credentials": { "url":"db.sqlite" }},
"ReviewsService": {
"kind": "odata", "model": "@capire/reviews"
},
@@ -29,9 +86,26 @@ To configure required remote services in Node.js, simply add respective entries
"kind": "odata", "model": "@capire/orders"
},
}
-}
+}}
+```
+
+```yaml [.cdsrc.yaml]
+cds:
+ requires:
+ db:
+ kind: sqlite
+ credentials:
+ url: db.sqlite
+ ReviewsService:
+ kind: odata,
+ model: @capire/reviews
+ OrdersService:
+ kind: odata,
+ model: @capire/orders
```
+:::
+
Entries in this section tell the service loader to not serve that service as part of your application, but expects a service binding at runtime in order to connect to the external service provider. The options are as follows:
@@ -104,147 +178,83 @@ If you specify a model, then a service definition for your required service must
The example specifies `service: 'BusinessPartnerService'`, which results in a check for a service called `BusinessPartnerService` instead of `remote-service` in the model loaded from `some/imported/model`.
-### cds.requires.\`.credentials`
-
-Specify the credentials to connect to the service. Credentials need to be kept secure and should not be part of a configuration file.
-
-
-
-
-
-## Connecting to Required Services { #cds-connect-to }
+## Service Bindings {#service-bindings}
-### cds. connect.to () {.method}
-
-Declaration:
-
-```ts:no-line-numbers
-async function cds.connect.to (
- name : string, // reference to an entry in `cds.requires` config
- options : {
- kind : string // reference to a preset in `cds.requires.kinds` config
- impl : string // module name of the implementation
- }
-)
-```
-
-Use `cds.connect.to()` to connect to services configured in a project's `cds.requires` configuration. Usually such services are remote services, which in turn can be mocked locally. Here's an example:
-
-::: code-group
+A service binding connects an application with a cloud service. For that, the cloud service's credentials need to be injected in the CDS configuration:
-```json [package.json]
-{"cds":{
- "requires":{
- "db": { "kind": "sqlite", "credentials": { "url":"db.sqlite" }},
- "ReviewsService": { "kind": "odata-v4" }
+```jsonc
+{
+ "requires": {
+ "db": {
+ "kind": "hana",
+ "credentials": { /* from service binding */ }
+ }
}
-}}
-```
-
-:::
-
-```js
-const ReviewsService = cds.connect.to('ReviewsService')
-const db = cds.connect.to('db')
-```
-
-Argument `options` allows to pass options programmatically, and thus create services without configurations, for example:
-
-```js
-const db2 = cds.connect.to ({
- kind: 'sqlite', credentials: { url: 'db2.sqlite' }
-})
+}
```
-In essence, `cds.connect.to()` works like that:
-```js
-let o = { ...cds.requires[name], ...options }
-let csn = o.model ? await cds.load(o.model) : cds.model
-let Service = require (o.impl) //> a subclass of cds.Service
-let srv = new Service (name, csn, o)
-return srv.init() ?? srv
-```
+### cds.requires.\.credentials
+All service binding information goes into this property. It's filled from the process environment when starting server processes, managed by deployment environments. Service bindings provide the details about how to reach a required service at runtime, that is, providing requisite credentials, most prominently the target service's `url`.
+You specify the credentials to be used for a service by using one of the following:
-### cds.connect.to (name, options?) → service
+- Process environment variables
+- Command line options
+- File system
+- Auto binding
-Connects to a required service and returns a _Promise_ resolving to a corresponding _[Service](../cds/cdl#services)_ instance.
-Subsequent invocations with the same service name all return the same instance.
+For example, in development, you can add them to a _.env_ file as follows:
-```js
-const srv = await cds.connect.to ('some-service')
-const { Books } = srv.entities
-await srv.run (SELECT.from(Books))
+```properties
+# .env file
+cds.requires.remote-service.credentials = { "url":"http://...", ... }
```
+::: warning β Never add secrets or passwords to _package.json_ or _.cdsrc.json_!
+General rule of thumb: `.credentials` are always filled (and overridden) from process environment on process start.
+:::
-_**Arguments:**_
-
-* `name` is used to look up connect options from [configured services](#cds-env-requires).
-* `options` allows to provide _ad-hoc_ options, overriding [configured ones](#cds-env-requires).
-
-
-_**Caching:**_
-
-Service instances are cached in [`cds.services`](cds-facade#cds-services), thus subsequent connects with the same service name return the initially connected one. As services constructed by [`cds.serve`](cds-serve#cds-serve) are registered with [`cds.services`](cds-facade#cds-services) as well, a connect finds and returns them as local service connections.
-
-If _ad-hoc_ options are provided, the instance is not cached.
-
-
-
-### cds.connect.to (options) → service
-
-Ad-hoc connection (→ only for tests):
-
-```js
-cds.connect.to ({ kind:'sqlite', credentials:{database:'my.db'} })
-```
+### Basic Mechanism {#bindings-via-cds-env}
-### cds.connect.to ('\:\') → service
-This is a shortcut for ad-hoc connections.
+The CAP Node.js runtime expects to find the service bindings in `cds.env.requires`.
-For example:
-```js
-cds.connect.to ('sqlite:my.db')
-```
+1. Configured required services constitute endpoints for service bindings.
-is equivalent to:
+ ```json
+ "cds": {
+ "requires": {
+ "ReviewsService": {...},
+ }
+ }
+ ```
-```js
-cds.connect.to ({kind: 'sqlite', credentials:{database:'my.db'}})
-```
+2. These are made available to the runtime via `cds.env.requires`.
+ ```js
+ const { ReviewsService } = cds.env.requires
+ ```
+3. Service Bindings essentially fill in `credentials` to these entries.
-## Service Bindings {#service-bindings}
+ ```js
+ const { ReviewsService } = cds.env.requires
+ ReviewsService.credentials = {
+ url: "http://localhost:4005/reviews"
+ }
+ ```
-A service binding connects an application with a cloud service. For that, the cloud service's credentials need to be injected in the CDS configuration:
+The latter is appropriate in test suites. In productive code, you never provide credentials in a hard-coded way. Instead, use one of the options presented in the following sections.
-```jsonc
-{
- "requires": {
- "db": {
- "kind": "hana",
- "credentials": { /* from service binding */ }
- }
- }
-}
-```
-You specify the credentials to be used for a service by using one of the following:
-- Environment variables
-- File system
-- Auto binding
-What to use depends on your environment.
### In Cloud Foundry {#bindings-in-cloud-platforms}
@@ -258,6 +268,8 @@ Cloud Foundry uses auto configuration of service credentials through the `VCAP_S
[Learn more about environment variables on Cloud Foundry and `cf env`.](https://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html){.learn-more}
+
+
#### Through `VCAP_SERVICES` env var {#vcap_services}
When deploying to Cloud Foundry, service bindings are provided in `VCAP_SERVICES` process environment variables, which is JSON-stringified array containing credentials for multiple services. The entries are matched to the entries in `cds.requires` as follows, in order of precedence:
@@ -373,6 +385,8 @@ Here are a few examples:
|