@cap-js-community/feature-toggle-library
Live-updatable feature toggles for CAP applications, backed by Redis.
Facts
Where it sits
Who is behind it
In the atlas: maintains 10@cap-js-communitymaintainercorporateuserContributes to this
In the atlas: contributes to 3@corporateuserJohannes VogelContributes to this
In the atlas: contributes to 25@johannes-vogelRichard LindnerContributes to this
In the atlas: contributes to 3@rlindner813 contributors
What it declares
Every artifact
- Type
- Package
- Origin
- By a community org
- Runtime
- Node.js
As a package
- Where it runs
- Inside its host
- Distributed through
- npm
Connections
Turning behaviour on and off per tenant or user at runtime
Managed Redis from the hyperscaler via a BTP service binding
An in-memory data store. For the things here it is the shared cache, the queue or the pub/sub channel that lets several application instances behave as one.
Download
Install
npm add @cap-js-community/feature-toggle-libraryDerived from the package name. No recipe recorded; the README has the configuration.
Where it sits in your app
Download
README
quoted from cap-js-community/feature-toggle-library under Apache-2.0, readSAP BTP Feature Toggle Library
SAP BTP feature toggle library enables Node.js applications using the SAP Cloud Application Programming Model to maintain live-updatable feature toggles via Redis.
Getting Started (CAP Feature Toggles)
-
Set up project with
@sap/cds. -
Install library:
npm install --save @cap-js-community/feature-toggle-library -
For CAP Feature Toggles everything is configured automatically.
-
The library acts as a CDS-Plugin and registers a
FeatureService, which can be used to check and update toggles. -
For details see Example CAP Server.
Getting Started (Custom Configuration)
-
Same as previous section.
-
Write
toggles.yamlconfiguration file:# info: check api priority; 0 means access is disabled /check/priority: type: number fallbackValue: 0 validations: - scopes: [user, tenant] - regex: '^\d+$' -
Add configuration path to
package.json:{ "cds": { "featureToggles": { "configFile": "./toggles.yaml" } } } -
Write usage code in handlers:
const toggles = require("@cap-js-community/feature-toggle-library"); const priorityHandler = async (context) => { const user = context.user.id; const tenant = context.tenant; const value = toggles.getFeatureValue("/check/priority", { user, tenant }); if (value <= 0) { return context.reject("blocked"); } else if (value < 10) { return context.reply("welcome"); } else { return context.reply("very welcome"); } };
Features
- Maintain feature toggle states consistently across multiple app instances.
- Feature toggle changes are published from Redis to subscribed app instances with publish/subscribe pattern PUB/SUB.
- Horizontal app scaling is supported and new app instances will start with the correct state, or fallback values, if they cannot connect to Redis.
- Feature toggle values can be changed specifically for accessors with certain scopes, e.g., for specific tenants, users,...
- Users can register change handler callbacks for specific toggles.
- Users can register custom input validation callbacks for specific toggles.
- Works as a CDS-Plugin and provides a REST service to read and manipulate toggles.
Peers
Documentation
Head over to our Documentation to learn more.
Support, Feedback, Contributing
This project is open to feature requests/suggestions, bug reports etc. via GitHub issues. Contribution and feedback are encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our Contribution Guidelines.
Code of Conduct
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone. By participating in this project, you agree to abide by its Code of Conduct at all times.
Licensing
Copyright 2023 SAP SE or an SAP affiliate company and feature-toggle-library contributors. Please see our LICENSE for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available via the REUSE tool.
History
Features 1, Changed 1
Notes
Changed
- redis: migrate to
@redis/clientv6. Cluster read-modify-write now uses the built-ingetNodeClientForKey()to obtain the node client owning a key's slot, replacing the manual slot calculation viacluster-key-slot(adopts fix for redis/node-redis#3194).
Added
- redis: add
LOCAL_REDIS_CLUSTERintegration mode, so cluster configuration is now detected locally as well.
- redis: migrate to
Changed 1
Notes
Changed
- redis: expand tls handling to work with more cloud providers: SAP Cloud Infrastructure (SCI), Azure, GCP (contributed by @corporateuser)
Removed 1, Changed 1
Notes
Removed
- cds-plugin: removed legacy plugin activation support for @sap/cds before v7.3.0.
Changed
- core: switch from
semaphoretoexecution-controlre-use module.
Changed 1, Fixes 1
Notes
Changed
- redis: migrate to @redis/client v5 with updated WATCH/MULTI/EXEC logic (fixes #114).
Fixed
- core: ignore mta blue-green deployment temporary appname suffixes -live and -idle (fixes #106).
Removed 1, Features 1, Changed 1
Notes
Changed
- cds-plugin: rely on file neighborhood for service implementation resolution. This helps for scenarios where the server's model is shared with mtx/sidecar and a local implementation is not present.
Removed
- restrict to at least node v20.
Added
- enable voters for node v24.
Features 1, Changed 1
Notes
Changed
- core: compatability changes for cds v9.
Added
- more testing for usage with cds.
Changed 4
Notes
⚠️ This release is potentially disruptive. Initialize will throw for previously ignored problems with configuration correctness. The coalesce logic for using multiple configuration sources has changed. For details see Layered Configuration.
Changed
-
core: initialization throws if mandatory configuration
fallbackValueisundefined(missing) ornull(always invalid). -
core: initialization throws if mandatory configuration
typeis not in["boolean", "number", "string"](invalid). -
core: initialization throws if its invoked more than once. previously subsequent calls and their options were ignored.
-
core: configuration reading and coalescing has changed:
- up to
v1.2.5, the order wasruntime,files,auto, where the first occurrence is used for each toggle - from
v1.3.0, the order isauto,files,runtime, where the last occurrence is used for each toggle - this enables overriding the configuration based on environmental factors, by mixing in dedicated config files
- up to
-
Fixes 2
Notes
Fixed
-
core: if a
./default-env.jsonfile was present andNODE_ENV !== "production", we had assumed that cf env variablesVCAP_APPLCATIONandVCAP_SERVICESare always present in the file. now this is more resilient. -
core: [regression] initialize timing was noticeably slower, because the initial connection check was running with the default reconnect strategy that takes 2000ms. now the reconnect strategy is disabled for the initial connection check.
-
Features 2, Changed 2
Notes
Changed
- cds-plugin: change default service access role to
internal-user(fixes #90). - redis: changed dependency from redis to @redis/client.
Added
-
core: [undocumented] plugin-config/initialize support multiple configuration files.
-
redis: [undocumented] cds-config/initialize take redis credentials and client options for fine-tuning or as an alternative to VCAP_SERVICES (brought up by #92).
the cds-config approach is consistent with the redis integration of other cap-js-community projects, see event-queue, websocket.
- cds-plugin: change default service access role to
Features 2, Fixes 2
Notes
Added
- cds-plugin: added explicit implementation for
FeatureService. - enable node v22 voters.
Fixed
- cds-plugin: allow feature toggles to initialize with no configured toggles.
- use proper cds syntax to get service operations (by johannes-vogel).
- cds-plugin: added explicit implementation for
Changed 1, Fixes 1
Notes
Changed
- the initialization log of the library will now show the unique name used. this name is used to derive both the redis storage key and pub/sub channel.
Fixed
- internal naming cleanup and consistency work.
Features 1, Changed 1, Fixes 1
Notes
Changed
- cds-plugin: service endpoint
/rest/feature/redisReadwill return server in-memory changes in NO_REDIS mode in order to be consistent with/rest/feature/redisUpdate.
Added
- cds-plugin: added
cds.test()basic request/response tests for service.
Fixed
- cds-plugin: service endpoint
/rest/feature/redisReadworks without http errors in NO_REDIS mode.
- cds-plugin: service endpoint
Features 2, Changed 2, Fixes 1
Notes
⚠️ This release contains two minor breaking changes.
Changed
-
The main class of the library is no longer explicitly exported. You can access it implicitly as constructor of the exported class instance.
// before const { FeatureToggles } = require("@cap-js-community/feature-toggle-library"); const myToggles = new FeatureToggles({ uniqueName: "snowflake" }); // after const toggles = require("@cap-js-community/feature-toggle-library"); const FeatureToggles = toggles.constructor; const myToggles = new FeatureToggles({ uniqueName: "snowflake" }); -
cds-plugin: rewrote
/rest/feature/redisReadendpoint to show all Redis maintained toggle values, including those of toggles that are not configured. The endpoint no longer refreshes the server-local toggle state. Consequently, it will work withreadaccess privileges, since it can no longer modify the server-local state (fixes #69).
Added
- added
remoteOnlyoption for/rest/feature/redisUpdateendpoint and thechangeFeatureValue()API. With this option, you can clean up Redis maintained values that are no longer configured (fixes #69). - cds-plugin: better detection of serve mode following changes in @sap/cds v8.2.3
Fixed
- multiple, even concurrent, calls of
initializeFeatures()will only ever trigger one execution of the underlying initialization.
-
Fixes 1
Notes
Fixed
- setting a root value with the option
{ clearSubScopes: true }only deleted the root and scoped values, but did not set the new root value.
- setting a root value with the option
Fixes 2
Notes
Fixed
- cds-plugin: fix
uniqueNameconfiguration processing - more consistent scope preference order when 2 out of 4 scopes are set
- cds-plugin: fix
Changed 2, Fixes 2
Notes
Changed
- fallback value
nullis no longer allowed (fixes #62). - change handlers no longer receive
nullas new values, they get the actual new value for the relevant scope instead (fixes #64).
Fixed
- cds-plugin: unify and fix syntax of
context.errorandcontext.rejectfor cds service. - change processing is more resilient. for redis message with multiple changes, if one change fails, then subsequent changes will still be processed.
- fallback value
Features 2, Fixes 1
Notes
Added
- docs: basic documentation for newest cds-plugin features.
- cds-plugin: better access control (fixes #57).
Fixed
- redis: better integration mode, will not log a connection error if redis is not present.
Features 3, Fixes 2
Notes
Added
- cds-plugin: fts feature toggles are detected and configured automatically (fixes #50).
- cds-plugin: allow custom scope map callback for fts feature toggles (fixes #51).
- cds-plugin: can configure unique name, i.e. which apps store the same toggles in redis, as part of cds configuration.
Fixed
- cds-plugin: feature toggles will not initialize during cds build.
- redis: proper usage of redis-client built-in reconnect capabilities.
Changed 2
Notes
Changed
- cds-service: always log update contents for traceability and improved logging for redis read and update errors.
- docs: add getting started section (fixes #43).
Changed 2
Notes
⚠️ User action required! This release will be more disruptive than usual. We re-thought that main
requireAPI and made it much leaner. These changes should have happened in 1.0, sorry for the inconvenience.// before const { singleton: { getFeatureValue }, } = require("@cap-js-community/feature-toggle-library"); function someFunc() { getFeatureValue(key); } // after const toggles = require("@cap-js-community/feature-toggle-library"); function someFunc() { toggles.getFeatureValue(key); }For details see https://cap-js-community.github.io/feature-toggle-library/usage/
Changed
- the library now exports only the singleton instance (fixes #39).
- cds-plugin: the request header features are only respected in development environments (fixes #41).
Removed 1, Features 2
Notes
We are releasing 1.0, after 2 years of continuous usage, testing, and small improvements.
Removed
- restrict to node v18+
Added
- act as Feature Vector Provider when used as a CDS-Plugin.
- allow graceful shutdown by closing redis clients on cds shutdown event (fixes #34).
Features 2, Changed 1
Notes
Added
- support for redis cluster configurations.
- enable setting maximal log level through env variable
BTP_FEATURES_LOG_LEVEL. this can be used to silence the library during tests.
Changed
- implement new CDS-Plugin API, where plugins export a promise instead of an activate property and stay compatible for older cds versions.
Fixes 1
Notes
Fixed
- CDS-Plugin integration now works for projects that run
cds build --productionand only use the resultingcsn.jsonat runtime.
- CDS-Plugin integration now works for projects that run
Features 3, Changed 2, Fixes 1
Notes
Added
-
new harmonized validation configuration for scope and regex checks, as well as external validation with user provided modules.
-
new (optional) CDS-Plugin integration. for details, see the new plugin and service documentation.
-
new logger implementation which replaces cf-nodejs-logging-support dependency. it has better cds integration (if present). for example, it will log correlation ids that are present in cds context via async local storage.
Changed
-
allowedScopes: [xxx]configuration will now be ignored and needs to be replaced withvalidations: [{ scopes: [xxx] }]. -
validation: yyyconfiguration will now be ignored and needs to be replaced withvalidations: [{ regex: yyy }].
Fixed
- re-work pipelines to separate main branch and pr-voter status
-
Features 1, Fixes 2
Notes
Added
- example http request file for example-cap-server
Fixed
-
better documentation regarding scoping and redis hash map persistence
-
more resilient handling of bad input for scopeMaps in all external APIs
Features 1, Fixes 1
Notes
Added
- added
allowedScopesconfiguration, which validates that correct scope names are used for updates
Fixed
- separate
rootValuefrom otherscopedValuesingetFeatureInfoandgetFeaturesInfosAPIs
- added
Features 1, Fixes 1
Notes
Added
- added
example-cap-servercode, that acts both as an example integration code into existing cap projects and as a starting point for manual testing
Fixed
- first iteration towards updating documentation
- added
Removed 1, Features 3, Fixes 2
Notes
Removed
- remove API to read feature config and metadata
getFeatureConfigandgetFeatureConfigs. usegetFeatureInfoandgetFeaturesInfosinstead
Added
-
new option to add scope restrictions when reading or setting feature toggles
-
separate persistence on redis using
HGET,HSET, so that individual toggle changes don't have to touch the state of all feature toggles. effectively we change the redis type for the persistence key fromstringtohash. -
new API
getFeatureInfoandgetFeaturesInfosto get all config and state information in one call
Fixed
-
rewrite to improve config handling internally
-
fix some problems with the logger in combination with verror
- remove API to read feature config and metadata
Removed 1, Features 1, Fixes 3
Notes
Removed
- restrict to node v16+
Added
- new interface to get
mainandsubscriberclient in redis wrapper
Fixed
-
better coding and interface for
LazyCacheandExpiringLazyCache -
more and improved jsdocs
-
allow options to be passed in redis wrapper
setimplementation. see SET for details.
Features 2
Notes
Added
-
local integration tests
-
write own env implementation replacing @sap/xsenv dependency
-
Fixes 1
Notes
Fixed
- more fixes related to error event handling in local case after redis library v4 migration
Removed 1, Fixes 1
Notes
Removed
- restrict to node v12+
Fixed
- fix
mainClientandsubscriberClientreference handling in error case
Features 1
Notes
Added
- allow to set singleton
uniqueNamevia env variableBTP_FEATURES_UNIQUE_NAME
- allow to set singleton
Removed 1, Features 2, Fixes 2
Notes
Removed
- config property
enabledis discontinued, useactiveinstead
Added
-
new config property:
active. if active is set to false, no changes of the feature toggle is allowed, but old value stays in place -
new API to read feature config and metadata
getFeatureConfigandgetFeatureConfigs
Fixed
-
change interface name
readConfigFromFilepathtoreadConfigFromFile -
change signature for
FeatureValueChangeHandlertohandler(newValue, oldValue)
- config property
Fixes 2
Notes
Fixed
-
make singleton more IDE friendly and ensure correctness with test
-
switch to artifactory registry
-
Features 1, Fixes 3
Notes
Added
- feature: external validation
Fixed
-
readme update
-
handler name fallback for anonymous functions
-
inputValidation is now async to account for potentially async external validators
Others providing
Compare all 5 on the Feature toggles page →- SAP Feature Flags serviceSAP Feature Flags serviceBoolean and string flags toggled in a dashboard and read by an application at runtime over a binding, with a cache in the client so a flip does not need a deploy or a round-trip per check.sap official, btpBoolean and string flags read by applications at runtime
- com.sap.cds:cds-services-bomcom.sap.cds:cds-services-bomThe Maven bill of materials for CAP Java, pinning every com.sap.cds module in a release, from the API and core runtime to the Spring Boot starters and the CQN engine, to the same version.sap official, capMaven bill of materials pinning CAP Java module versions
- @sap/cds-mtxs@sap/cds-mtxsMultitenancy, tenant provisioning and model extensibility for CAP.sap official, capMultitenancy, tenant provisioning and extensibility for CAP
- cds-feature-togglecds-feature-toggleA feature-toggle pattern for CAP CDS from before the core had one, sitting at the CDS layer rather than the tenant-extensibility layer of @sap/cds-mtxs feature toggles.independent, capFeature-toggle pattern for CAP CDS
Details
Sources
Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.
Compatibility and provenance
Contributors
History in the atlas
- First seen.
For your agent
- Ref
artifact:cap-js-community-feature-toggle-library- JSON
- /artifacts/cap-js-community-feature-toggle-library.json
- MCP
- Connecting an agent