@sourceloop/feature-toggle-service

中文文档
9.1.2发布于 2026/11/02MITTypeScriptCommonJS构建来源已验证

提供特性切换功能的服务。

中文使用文档
文档目录10 节
  1. 概述
  2. 工作流程
  3. 安装
  4. 使用
  5. 非对称令牌签名和验证
  6. 环境变量
  7. 建立 DataSource
  8. 迁移
  9. API文档
  10. 常见的反应

@sourceloop / feature-toggle-service

LoopBack

npm

node-current (scoped)

npm (prod) dependency version (scoped)

概述

提供维护不同级别特性标志的功能的微服务。提供了对系统级、租户级和用户级的初始支持。

工作流程

该服务提供了CRUD api,用于将值插入到特定于特性切换的数据表中,这些数据表在决定是否允许用户使用某个特定特性时可以读取。 这个特性是feature-toggle包的扩展——@sourceloop/feature-toggle,它提供了一个方法级装饰器来检查特定的API是否可访问。

提供了系统级、租户级和用户级特性标志的初始实现。

安装


npm i @sourceloop/feature-toggle-service

使用

  • 创建一个新的Loopback4应用程序(如果你还没有一个)lb4 testapp
  • 安装服务- npm i @sourceloop/feature-toggle-service
  • 设置 环境变量
  • 运行 迁移。(这将在数据库中创建相应的表)
  • 添加 FeatureToggleServiceComponent 到您的Loopback4应用程序(在 application.ts)。
    // import the FeatureToggleServiceComponent
    import {FeatureToggleServiceComponent} from '@sourceloop/feature-toggle-service';
    // add controllers to your application (optional)
    this.bind(FeatureToggleBindings.Config).to({
      bindControllers: true,
      useCustomSequence: false,
    });
    // add Component for FeatureToggleService
    this.component(FeatureToggleServiceComponent);
    
  • 建立一个 Loopback4数据源 与 dataSourceName 属性设置为 FeatureToggleDbName。您可以看到一个示例数据源 在这里.
  • 启动应用程序 npm start

非对称令牌签名和验证

如果您正在使用非对称令牌签名和验证,则应该在服务中提供认证数据源,并在facade级别上提供认证数据源。auth数据库的数据源文件示例为:-

验证DB数据源:-

import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {juggler} from '@loopback/repository';
import {AuthDbSourceName} from '@sourceloop/core';
const DEFAULT_MAX_CONNECTIONS = 25;
const DEFAULT_DB_IDLE_TIMEOUT_MILLIS = 60000;
const DEFAULT_DB_CONNECTION_TIMEOUT_MILLIS = 2000;

const config = {
  name: 'auth',
  connector: 'postgresql',
  host: process.env.DB_HOST,
  port: process.env.DB_PORT,
  user: process.env.DB_USER,
  schema: process.env.DB_SCHEMA,
  password: process.env.DB_PASSWORD,
  database: process.env.AUTH_DB,
};

// Observe application's life cycle to disconnect the datasource when
// application is stopped. This allows the application to be shut down
// gracefully. The `stop()` method is inherited from `juggler.DataSource`.
// Learn more at https://loopback.io/doc/en/lb4/Life-cycle.html
@lifeCycleObserver('datasource')
export class AuthDataSource
  extends juggler.DataSource
  implements LifeCycleObserver
{
  static dataSourceName = AuthDbSourceName;

  static readonly defaultConfig = config;

  constructor(
    @inject('datasources.config.auth', {optional: true})
    dsConfig: object = config,
  ) {
    if (!!+(process.env.ENABLE_DB_CONNECTION_POOLING ?? 0)) {
      const dbPool = {
        max: +(process.env.DB_MAX_CONNECTIONS ?? DEFAULT_MAX_CONNECTIONS),
        idleTimeoutMillis: +(
          process.env.DB_IDLE_TIMEOUT_MILLIS ?? DEFAULT_DB_IDLE_TIMEOUT_MILLIS
        ),
        connectionTimeoutMillis: +(
          process.env.DB_CONNECTION_TIMEOUT_MILLIS ??
          DEFAULT_DB_CONNECTION_TIMEOUT_MILLIS
        ),
      };

      dsConfig = {...dsConfig, ...dbPool};
    }

    super(dsConfig);
  }
}

验证Cache Redis数据源:-

import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {AnyObject, juggler} from '@loopback/repository';
import {readFileSync} from 'fs';
import {AuthCacheSourceName} from '@sourceloop/core';

const config = {
  name: process.env.REDIS_NAME,
  connector: 'kv-redis',
  host: process.env.REDIS_HOST,
  port: process.env.REDIS_PORT,
  password: process.env.REDIS_PASSWORD,
  db: process.env.REDIS_DATABASE,
  url: process.env.REDIS_URL,
  tls:
    +process.env.REDIS_TLS_ENABLED! && process.env.REDIS_TLS_CERT
      ? {
          ca: readFileSync(process.env.REDIS_TLS_CERT),
        }
      : undefined,
  sentinels:
    +process.env.REDIS_HAS_SENTINELS! && process.env.REDIS_SENTINELS
      ? JSON.parse(process.env.REDIS_SENTINELS)
      : undefined,
  sentinelPassword:
    +process.env.REDIS_HAS_SENTINELS! && process.env.REDIS_SENTINEL_PASSWORD
      ? process.env.REDIS_SENTINEL_PASSWORD
      : undefined,
  role:
    +process.env.REDIS_HAS_SENTINELS! && process.env.REDIS_SENTINEL_ROLE
      ? process.env.REDIS_SENTINEL_ROLE
      : undefined,
};

@lifeCycleObserver('datasource')
export class RedisDataSource
  extends juggler.DataSource
  implements LifeCycleObserver
{
  static readonly dataSourceName = AuthCacheSourceName;
  static readonly defaultConfig = config;

  constructor(
    @inject(`datasources.config.${process.env.REDIS_NAME}`, {optional: true})
    dsConfig: AnyObject = config,
  ) {
    if (
      +process.env.REDIS_HAS_SENTINELS! &&
      !!process.env.REDIS_SENTINEL_HOST &&
      !!process.env.REDIS_SENTINEL_PORT
    ) {
      dsConfig.sentinels = [
        {
          host: process.env.REDIS_SENTINEL_HOST,
          port: +process.env.REDIS_SENTINEL_PORT,
        },
      ];
    }
    super(dsConfig);
  }
}

环境变量

名字要求默认值描述
NODE_ENVY节点环境值,即 dev, test, prod
LOG_LEVELY日志级别值,即 error, warn, info, verbose, debug
DB_HOSTY数据库服务器的主机名。
DB_PORTY数据库服务器的端口。
DB_USERY数据库的用户。
DB_PASSWORDY数据库用户的密码。
DB_DATABASEY数据库服务器上要连接的数据库。
DB_SCHEMAY用于数据源的数据库模式。在PostgreSQL中,这将是 public 除非为服务显式地制定了模式。
JWT_SECRETYJWT令牌的对称签名密钥。
JWT_ISSUERYJWT令牌的发行者。

建立 DataSource

下面是一个示例实现 DataSource 使用环境变量和PostgreSQL作为数据源实现。

import {inject, lifeCycleObserver, LifeCycleObserver} from '@loopback/core';
import {juggler} from '@loopback/repository';
import {FeatureToggleDbName} from '@sourceloop/feature-toggle-service';

const config = {
  name: FeatureToggleDbName,
  connector: 'postgresql',
  url: '',
  host: process.env.DB_HOST,
  port: process.env.DB_PORT,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_DATABASE,
  schema: process.env.DB_SCHEMA,
};

@lifeCycleObserver('datasource')
export class FeatureToggleDbDataSource
  extends juggler.DataSource
  implements LifeCycleObserver
{
  static dataSourceName = FeatureToggleDbName;
  static readonly defaultConfig = config;

  constructor(
    @inject('datasources.config.feature', {optional: true})
    dsConfig: object = config,
  ) {
    super(dsConfig);
  }
}

迁移

此服务所需的迁移将在安装过程中自动处理 FEATURETOGGLE_MIGRATION 或者 SOURCELOOP_MIGRATION env变量。迁移使用 db-migrate 与 db-migrate-pg 驱动程序,因此您必须安装这些包才能使用自动迁移。请注意,如果您正在使用一些预先存在的迁移或数据库,它们可能会受到影响。在这种情况下,建议您在项目根目录下复制迁移文件,使用 FEATURETOGGLE_MIGRATION_COPY 或者 SOURCELOOP_MIGRATION_COPY env变量。您可以根据您的特定需求定制或挑选复制文件中的迁移,然后将它们应用到DB。

这个迁移脚本同时支持MySQL和PostgreSQL数据库,由环境变量控制。通过设置MYSQL_MIGRATION为“true”,脚本使用MySQL配置文件运行迁移;否则,默认为PostgreSQL。

此外,现在有一个选项可以选择SQL迁移或PostgreSQL迁移。 注:对于 @sourceloop/cli 用户可以在搭建过程中通过选择“数据源类型”选项来指定此选项。

API文档

常见的头

授权:承载,其中是使用JWT颁发者和密钥签名的JWT令牌。 Content-Type: application/json 如果API方法不是GET,则在响应和请求中

常用请求路径参数

{version}:定义API的版本

常见的反应

200:成功响应。响应体随API的变化而变化 401: Unauthorized: JWT令牌缺失或无效 403: Forbidden:不允许执行相关API 404:实体未找到 400:错误请求(错误消息随API的不同而不同) 201: No content: Empty Response

API的细节

参观 OpenAPI规范文档

版本与发布记录

@sourceloop/feature-toggle-service 共发布 101 个版本,首次发布于 2021/10/25;过去 12 个月发布了 9 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
9.1.2latest2026/11/02今天
9.1.12026/09/101 个月前
9.1.02026/08/162 个月前
9.0.02026/06/194 个月前
8.0.62026/03/097 个月前
8.0.52026/02/208 个月前

关于 @sourceloop/feature-toggle-service 的常见问题

@sourceloop/feature-toggle-service 是什么?

提供特性切换功能的服务。

如何安装 @sourceloop/feature-toggle-service?

在项目目录运行 npm install @sourceloop/feature-toggle-service,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:db-migrate(^1.0.0-beta.21)、db-migrate-pg(^1.3.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@sourceloop/feature-toggle-service 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@sourceloop/feature-toggle-service 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@sourceloop/feature-toggle-service 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js 22 || 24。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@sourceloop/feature-toggle-service 可以商用吗?

@sourceloop/feature-toggle-service 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@sourceloop/feature-toggle-service 还在维护吗?

最新版本 9.1.2 发布于 2026/11/02(今天);至今共发布 101 个版本,其中过去 12 个月发布了 9 个;首次发布于 2021/10/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。