diff --git a/guides/deploy/build.md b/guides/deploy/build.md
index c62a26f67..c86e233f8 100644
--- a/guides/deploy/build.md
+++ b/guides/deploy/build.md
@@ -23,7 +23,7 @@ cds build --production
Build tasks are derived from the CDS configuration and project context. By default, CDS models are resolved from these sources:
- _db/_, _srv/_, _app/_ — default root folders of a CAP project
-- _fts/_ and its subfolders when using [feature toggles](../extensibility/feature-toggles#enable-feature-toggles)
+- _fts/_ and its subfolders when using [feature toggles](../extensibility/feature-toggles#enable-feature-toggles-in-node-js)
- CDS model folders and files defined by [required services](../../node.js/cds-env#services)
- Built-in examples: [Event Queues](../../node.js/event-queues#configuration) or [MTX-related services](../multitenancy/mtxs#mtx-services-reference)
- Explicit `src` folder configured in the build task
diff --git a/guides/extensibility/feature-toggles.md b/guides/extensibility/feature-toggles.md
index 97c06dbfb..a3b52d7e9 100644
--- a/guides/extensibility/feature-toggles.md
+++ b/guides/extensibility/feature-toggles.md
@@ -1,58 +1,48 @@
---
synopsis: >
Toggled features are pre-built extensions built by the provider of a SaaS application, which can be switched on selectively per subscriber.
-impl-variants: true # to enable Node.js/Java toggle
---
# Feature Toggles
{{$frontmatter?.synopsis}}
-
-
## Introduction and Overview
CAP feature-toggled aspects allow SaaS providers to create pre-built features as CDS models, extending the base models with new fields, entities, as well as annotations for SAP Fiori UIs. These features can be assigned to individual SaaS customers (tenants), users, and requests and are then activated dynamically at runtime, as illustrated in the following figure.

-### Get `cloud-cap-samples-java` for step-by-step Exercises {.java}
-
-The following steps will extend the [CAP samples for Java](https://github.com/SAP-samples/cloud-cap-samples-java) app to demonstrate how features can extend data models, services, as well as SAP Fiori UIs. If you want to exercise these steps, get [cloud-cap-samples-java](https://github.com/SAP-samples/cloud-cap-samples-java) before, and prepare to extend the *Fiori* app:
+### Get Sample for Step-By-Step Exercises
-
+The following steps will extend the [CAP samples for Java](https://github.com/SAP-samples/cloud-cap-samples-java) / [cap/samples/bookstore](https://github.com/capire/bookstore) app to demonstrate how features can extend data models, services, as well as SAP Fiori UIs. If you want to exercise these steps, get [cloud-cap-samples-java](https://github.com/SAP-samples/cloud-cap-samples-java) before, and prepare to extend the *Fiori* (Java) / *bookstore* (Node.js) app:
-```sh
+::: code-group
+```sh [Java]
git clone https://github.com/SAP-samples/cloud-cap-samples-java
cd cloud-cap-samples-java
mvn clean install
```
-
-
-
-Now, open the app in your editor, for example, for VS Code type:
-
-```sh
-code .
-```
-
-### Get `cap/samples` for Step-By-Step Exercises {.node}
-
-The following steps will extend the [cap/samples/bookstore](https://github.com/capire/bookstore) app to demonstrate how features can extend data models, services, as well as SAP Fiori UIs. If you want to exercise these steps, get [cap/samples](https://github.com/capire/samples) before, and prepare to extend the *bookstore* app:
-
-```sh
+```sh [Node.js]
git clone --recurse-submodules https://github.com/capire/samples
cd samples
npm install
```
-Now, open the `bookstore` app in your editor, for example, by this if you're using VS Code on macOS:
+:::
-```sh
+Now, open the app in your editor, for example, for VS Code type:
+
+::: code-group
+```sh [Java]
+code .
+```
+```sh [Node.js]
code bookstore
```
+:::
-## Enable Feature Toggles {.node}
+## Enable Feature Toggles in Node.js
### Add `@sap/cds-mtxs` Package Dependency
@@ -130,11 +120,10 @@ In principle, features can be toggled per request, per user, or per tenant; most
### In Development
-
+CAP Node.js' `mocked-auth` strategy has built-in support for toggling features per tenant, per user, or per request. CAP Java's [Mock User Authentication with Spring Boot](../../java/security#mock-users) allows to assign feature toggles to users based on the mock user configuration. To demonstrate toggling features per tenant, or user, you can add these lines of configuration to our `package.json` of the SAP Fiori app (Node.js) or to the mock user configuration in the `srv/src/main/resources/application.yaml` file (CAP Java).
-CAP Node.js' `mocked-auth` strategy has built-in support for toggling features per tenant, per user, or per request. To demonstrate toggling features per tenant, or user, you can add these lines of configuration to our `package.json` of the SAP Fiori app:
-
-```json
+::: code-group
+```json [Node.js: package.json]
{"cds":{
"requires": {
"auth": {
@@ -152,13 +141,7 @@ CAP Node.js' `mocked-auth` strategy has built-in support for toggling features p
}}
```
-
-
-
-
-CAP Java's [Mock User Authentication with Spring Boot](../../java/security#mock-users) allows to assign feature toggles to users based on the mock user configuration. To demonstrate toggling features per user, you can add these lines to the mock user configuration in the `srv/src/main/resources/application.yaml` file:
-
-```yaml
+```yaml [Java: application.yaml]
cds:
security.mock.users:
- name: carol
@@ -171,37 +154,33 @@ cds:
- name: fred
features:
```
-
-
+:::
In effect of this, for the user `carol` the feature `isbn` is enabled, for `erin`, the features `isbn` and `reviews` are enabled, and for the user `fred` all features are disabled.
### In Production
-
-
-::: warning No features toggling for production yet
-Note that the previous sample is only for demonstration purposes. As user and tenant management is outside of CAP's scope, there's no out-of-the-box feature toggles provider for production yet. → Learn more about that in the following section [*Feature Vector Providers*](#feature-vector-providers).
+::: warning Bring your own toggle provider for production
+Note that the previous sample is only for demonstration purposes. As user and tenant management is outside of CAP's scope, there's no out-of-the-box feature toggles provider for production yet. → Learn more about that in the following section [*Feature Vector Providers*](#feature-vector-providers-in-node-js).
:::
-
-
-
+#### In CAP Java
-For productive use, the mock user configuration must not be used. The set of active features is determined per request by the [Feature Toggles Info Provider](../../java/reflection-api#feature-toggles-info-provider).
+For productive use in CAP Java, the mock user configuration must not be used. The set of active features is determined per request by the [Feature Toggles Info Provider](../../java/reflection-api#feature-toggles-info-provider).
You can register a [Custom Implementation](../../java/reflection-api#custom-implementation) as a Spring bean that computes the active feature set based on the request's `UserInfo` and `ParameterInfo`.
-
-
-## Test-Drive Locally {.node}
+## Test-Drive Locally in Node.js
To test feature toggles, just run your CAP server as usual, then log on with different users, assigned to different tenants, to see the effects.
+> [!INFO] Local test with CAP Java and sidecar
+> How to test a CAP Java project locally is described in [Model Provider in Sidecar](#model-provider-in-sidecar).
+
### Run `cds watch`
Start the CAP server with `cds watch` as usual:
@@ -221,7 +200,7 @@ cds watch
> The `ModelProviderService` is used by the runtime to get feature-enhanced models.
-### See Effects in SAP Fiori UIs {#test-fiori-node}
+### See Effects in SAP Fiori UIs
To see the effects in the UIs open three anonymous browser windows, one for each user to log in, and:
@@ -238,15 +217,13 @@ For example the displayed UI should look like that for `erin`:
The `ModelProviderService`, which is used for toggling features, is implemented in Node.js only. To use it with CAP Java apps, you run it in a so-called *MTX sidecar*. For a CAP Node.js project, this service is always run embedded with the main application.
-### Create Sidecar as Node.js Project
+### Create Sidecar
An MTX sidecar is a standard, yet minimalistic Node.js CAP project. By default it's added to a subfolder *mtx/sidecar* within your main project, containing just a *package.json* file:
-
-
::: code-group
-```json [mtx/sidecar/package.json]
+```json [Node.js: mtx/sidecar/package.json]
{
"name": "mtx-sidecar", "version": "0.0.0",
"dependencies": {
@@ -259,16 +236,7 @@ An MTX sidecar is a standard, yet minimalistic Node.js CAP project. By default i
}
```
-:::
-
-
-
-
-
-
-::: code-group
-
-```json [mtx/sidecar/package.json]
+```json [Java: mtx/sidecar/package.json]
{
"name": "mtx-sidecar", "version": "0.0.0",
"dependencies": {
@@ -283,16 +251,13 @@ An MTX sidecar is a standard, yet minimalistic Node.js CAP project. By default i
}
}
```
-
:::
-
-
[Learn more about setting up **MTX sidecars**.](../multitenancy/mtxs#sidecars){.learn-more}
### Add Remote Service Link to Sidecar
-
+#### In Node.js
::: tip
In Node.js apps you usually don't consume services from the sidecar. The *ModelProviderService* is served both, embedded in the main app as well as in the sidecar. The following is documented for the sake of completeness only...
@@ -311,9 +276,7 @@ You can use the `from-sidecar` preset to tell the CAP runtime to use the remote
[Learn more about configuring ModelProviderService.](../multitenancy/mtxs#model-provider-config){.learn-more}
-
-
-
+#### In CAP Java
You need to configure the CAP Java application to request the CDS model from the Model Provider Service.
This is done in the `application.yaml` file of your application.
@@ -328,8 +291,6 @@ cds:
extensibility: false
```
-
-
### Test-Drive Sidecar Locally
With the setup as described in place, you can run the main app locally with the Model Provider as sidecar. Simply start the main app and the sidecar in two separate shells:
@@ -342,27 +303,22 @@ cds watch mtx/sidecar
**Then, start the main app** in the second shell:
-
-
-```sh
+::: code-group
+```sh [Node.js]
cds watch
```
-
-
-
-
-
-```sh
+```sh [Java]
mvn spring-boot:run
```
-
+:::
+
-#### Remote `getCsn()` Calls to Sidecar at Runtime {.node}
+#### Remote `getCsn()` Calls to Sidecar at Runtime in Node.js
-When you now run and use our application again as described in the previous section [See Effects in SAP Fiori UIs](#test-fiori-node), you can see in the trace logs that the main app sends `getCsn` requests to the sidecar, which in response to that reads and returns the main app's models. That means, the models from two levels up the folder hierarchy as configured by `root: ../..` for development.
+When you now run and use our application again as described in the previous section [See Effects in SAP Fiori UIs](#see-effects-in-sap-fiori-uis), you can see in the trace logs that the main app sends `getCsn` requests to the sidecar, which in response to that reads and returns the main app's models. That means, the models from two levels up the folder hierarchy as configured by `root: ../..` for development.
-### See Effects in SAP Fiori UIs {#test-fiori-java .java}
+### See Effects in SAP Fiori UIs in CAP Java
To see the effects in the UIs open three anonymous browser windows, one for each user to log in, and:
@@ -375,7 +331,7 @@ For example the displayed UI should look like that for `erin`:

-## Feature Vector Providers {.node}
+## Feature Vector Providers in Node.js
In principle, features can be toggled *per request* using the `req.features` property (`req` being the standard HTTP req object here, not the CAP runtimes `req` object). This property is expected to contain one of the following:
@@ -395,7 +351,7 @@ cds.on('bootstrap', app => app.use ((req,res,next) => {
## Feature-Toggled Custom Logic
-
+### In CAP Java
[Evaluate the `FeatureTogglesInfo` in custom code](../../java/reflection-api#using-feature-toggles-in-custom-code) to check if a feature is enabled:
@@ -409,9 +365,7 @@ if (features.isEnabled("discount")) {
}
```
-
-
-
+### In Node.js
Within your service implementations, you can react on feature toggles by inspecting `cds.context.features` like so:
@@ -437,6 +391,4 @@ if (reviews) {
// specific coding when feature 'reviews' is enabled...
}
// common coding...
-```
-
-
+```
\ No newline at end of file
diff --git a/java/event-queues.md b/java/event-queues.md
index 3211862e6..c3261d79f 100644
--- a/java/event-queues.md
+++ b/java/event-queues.md
@@ -524,7 +524,7 @@ A startup log entry shows the configured version:
2024-12-19T11:21:33.253+01:00 INFO 3420 --- [main] cds.services.impl.utils.BuildInfo : application.deployment.version: 1.0.0-SNAPSHOT
```
-To bypass the version check for a specific custom outbox, set [`cds.outbox.services.MyCustomOutbox.checkVersion: false`](./developing-applications/properties#cds-outbox-services--checkVersion).
+To bypass the version check for a specific custom outbox, set [`cds.outbox.services.MyCustomOutbox.checkVersion: false`](./developing-applications/properties#cds-outbox-services--checkversion).
## Troubleshooting
diff --git a/node.js/cds-serve.md b/node.js/cds-serve.md
index 4bc99ed3c..443680879 100644
--- a/node.js/cds-serve.md
+++ b/node.js/cds-serve.md
@@ -337,7 +337,7 @@ cds.middlewares.before = [
]
```
-[Learn more about Feature Vector Providers.](../guides/extensibility/feature-toggles#feature-vector-providers){.learn-more}
+[Learn more about Feature Vector Providers.](../guides/extensibility/feature-toggles#feature-vector-providers-in-node-js){.learn-more}
### Current Limitations