Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Plugin and Service

Plugin Settings

Here is a list of all plugin settings that can be used in package.json under this library’s node cds.featureToggles. All settings are optional.

setting type meaning
configFile string path of the configuration file
config object inline configuration (only recommended for small projects)
uniqueName string key name on redis, see below
serviceAccessRoles array read and write access roles, see below
readAccessRoles array see below
writeAccessRoles array see below
adminAccessRoles array see below
ftsScopeCallback string custom scopes for cap feature toggles, see below

uniqueName
The unique name is an identifier for the state data in redis. This defaults to the cloud foundry application name and usually need not be changed. Sometimes multiple apps want to access the same state though. In this case you would give all of them the same unique name. See single-key-approach for a diagram.

serviceAccessRoles, readAccessRoles, writeAccessRoles, adminAccessRoles
By default the FeatureService read and write endpoints are accessible only to users with the CAP pseudo-role system-user. Different projects have their own access role preferences, so this setting allows them to set a list of strings, which represent the roles required to access the service. For details see @requires.

It will usually be sufficient to set the serviceAccessRoles configuration, which covers both the read and write endpoints, but not the admin endpoints. If more discriminating access control is required, the readAccessRoles and writeAccessRoles can be set separately. For debugging purposes, you can also set the adminAccessRoles.

As the name suggests, the adminAccessRoles should be considered sensitive. It allows direct root access to the underlying redis.

ftsScopeCallback
First, read the Feature Vector Provider section for background. It may make sense to change the runtime scope for CAP Feature Toggles. For example, you might have a request header present that should be used as scope to distinguish toggle values. For this use-case:

  • Create a file, e.g., srv/feature/ftsScope.js:
/**
 * @param context  cds context
 * @param key      toggle key, to use different scopes for different toggles
 */
module.exports = (context, key) => {
  const companyId; // your code here
  return {
    user: context?.user?.id,
    tenant: context?.tenant,
    companyId,
  }
}
  • Configure this file in package.json:
{
  "cds": {
    "featureToggles": {
      "ftsScopeCallback": "./srv/feature/ftsScope.js"
    }
  }
}

Feature Vector Provider

When used as a CDS-Plugin, the library will automatically act as a Feature Vector Provider. This means feature toggles which match the /fts/<feature-name> pattern and have a truthy current value at the start of a request will be passed to CDS, as they expect it, in req.features.

In practice, if you have a CDS model extension feature in the directory <project>/fts/my-feature, the library will automatically detect it and configure it as follows:

/fts/my-feature:
  type: boolean
  fallbackValue: false

This automatic configuration can be overwritten, by using a configuration file and adding a dedicated configuration with the same key /fts/my-feature.

You can check and modify these feature toggles similarly to all others, and it will be provided to CDS and respected for the related requests. For an example check out the Example CAP Server.

Service Endpoints for Read Privilege

This service endpoint will enable operations teams to understand toggle states. For practical requests, check the http file in our example CAP Server.

Read Feature Toggles State

Get all information about the current in-memory state of all toggles.

Example Request/Response

  • Request
    GET /rest/feature/state
    Authorization: ...
    
  • Response
    HTTP/1.1 200 OK
    ...
    
    {
      "/check/priority": {
        "fallbackValue": 0,
        "config": {
          "SOURCE": "FILE",
          "TYPE": "number",
          "VALIDATIONS": [
            {
              "scopes": ["user", "tenant"]
            },
            {
              "regex": "^\\d+$"
            },
            {
              "module": "$CONFIG_DIR/validators",
              "call": "validateTenantScope"
            }
          ]
        }
      },
      "/memory/logInterval": {
        "fallbackValue": 0,
        "config": {
          "SOURCE": "FILE",
          "TYPE": "number",
          "VALIDATIONS": [
            {
              "regex": "^\\d+$"
            }
          ]
        }
      },
      "/fts/check-service-extension": {
        "fallbackValue": false,
        "config": {
          "SOURCE": "AUTO",
          "TYPE": "boolean"
        }
      }
    }
    

Service Endpoints for Write Privilege

Similar to the read privilege endpoints, these endpoints are meant to modify toggle state. For practical requests, check the http file in our example CAP Server.

Update Feature Toggle

Update the toggle state on Redis, which in turn is published to all server instances.

Example Request/Responses

  • Valid Request
    POST /rest/feature/redisUpdate
    Authorization: ...
    Content-Type: application/json
    
    {
      "key": "/check/priority",
      "value": 10,
      "scope": { "tenant": "people" }
    }
    
  • Response

    HTTP/1.1 204 No Content
    ...
    
  • Valid Request with clearSubScopes
    POST /rest/feature/redisUpdate
    Authorization: ...
    Content-Type: application/json
    
    {
      "key": "/check/priority",
      "value": 10,
      "options": {
        "clearSubScopes": true
      }
    }
    
  • Response

    HTTP/1.1 204 No Content
    ...
    
  • Invalid Request
    POST /rest/feature/redisUpdate
    Authorization: ...
    Content-Type: application/json
    
    {
      "key": "/check/priority",
      "value": "test"
    }
    
  • Response
    HTTP/1.1 422 Unprocessable Entity
    ...
    
    {
      "error": {
        "message": "value \"test\" has invalid type string, must be number",
        "code": "422",
        "@Common.numericSeverity": 4
      }
    }
    

Re-Sync Server with Redis

Force server to re-sync with Redis, this should never be necessary. It returns the same JSON structure as /state, after re-syncing.

Example Request/Response

Service Endpoints for Admin Privilege

The service also offers an additional endpoint for deep problem analysis.

Send Redis Command

Send an arbitrary command to Redis. https://redis.io/commands/

Example Request/Responses

  • Request INFO
    POST /rest/feature/redisSendCommand
    Authorization: ...
    Content-Type: application/json
    
    {
      "command": ["INFO"]
    }
    
  • Response
    HTTP/1.1 200 OK
    ...
    
    # Server
    redis_version:4.0.10
    redis_git_sha1:0
    redis_git_dirty:0
    redis_build_id:0
    ...
    
  • Request KEYS
    POST /rest/feature/redisSendCommand
    Authorization: ...
    Content-Type: application/json
    
    {
      "command": ["KEYS", "features-*"]
    }
    
  • Response
    HTTP/1.1 200 OK
    ...
    
    ["features-...", "..."]