# @sourceloop/feature-toggle-service 中文文档

规范地址：https://npmcn.com/package/%40sourceloop/feature-toggle-service/

版本：9\.1\.2
npm 元数据更新时间：2026-11-02T11:33:50.684Z
中文译文更新时间：2026-11-02T13:11:39.607Z
软件包许可：MIT

本文由上游 README 机器翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40sourceloop/feature-toggle-service
原文对照：https://npmcn.com/package/%40sourceloop/feature-toggle-service/?lang=original
项目主页：https://github.com/sourcefuse/loopback4-microservice-catalog#readme
源码仓库：https://github.com/sourcefuse/loopback4-microservice-catalog

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：184 kB，106 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- Node.js 要求：22 \|\| 24
- 运行依赖：18 个
- peer 依赖：db-migrate ^1\.0\.0-beta\.21，db-migrate-pg ^1\.3\.0
- 首次发布：2021-10-24T22:37:08.136Z
- 最新版本发布：2026-11-02T11:33:49.893Z
- 已发布版本数：101（近 12 个月 9 个）

## 中文简介

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

## 安装

```sh
npm install @sourceloop/feature-toggle-service
```

也可以使用：`pnpm add @sourceloop/feature-toggle-service`、`yarn add @sourceloop/feature-toggle-service`、`bun add @sourceloop/feature-toggle-service`

## README

# @sourceloop / feature-toggle-service

[![LoopBack](https://github.com/strongloop/loopback-next/raw/master/docs/site/imgs/branding/Powered-by-LoopBack-Badge-\(blue\)-@2x.png)](http://loopback.io/)

![npm](https://img.shields.io/npm/dm/@sourceloop/feature-toggle-service)

![node-current (scoped)](https://img.shields.io/node/v/@sourceloop/feature-toggle-service)

![npm (prod) dependency version (scoped)](https://img.shields.io/npm/dependency-version/@sourceloop/feature-toggle-service/@loopback/core)

## 概述

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

## 工作流程

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

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

## 安装

```bash

npm i @sourceloop/feature-toggle-service
```

## 使用

-   创建一个新的Loopback4应用程序（如果你还没有一个）lb4 testapp
-   安装服务- npm i @sourceloop/feature-toggle-service
-   设置 [环境变量](https://npmcn.com/package/%40sourceloop/feature-toggle-service/#readme-environment-variables)
-   运行 [迁移](https://npmcn.com/package/%40sourceloop/feature-toggle-service/#readme-migrations)。（这将在数据库中创建相应的表）
-   添加 `FeatureToggleServiceComponent` 到您的Loopback4应用程序(在 `application.ts`）。
    
    ```typescript
    // 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数据源](https://loopback.io/doc/en/lb4/DataSource.html) 与 `dataSourceName` 属性设置为 `FeatureToggleDbName`。您可以看到一个示例数据源 [在这里](https://npmcn.com/package/%40sourceloop/feature-toggle-service/#readme-setting-up-a-datasource).
-   启动应用程序 `npm start`

### 非对称令牌签名和验证

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

验证DB数据源：-

```ts
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数据源：-

```ts
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_ENV` | Y |  | 节点环境值，即 `dev`， `test`， `prod` |
| `LOG_LEVEL` | Y |  | 日志级别值，即 `error`， `warn`， `info`， `verbose`， `debug` |
| `DB_HOST` | Y |  | 数据库服务器的主机名。 |
| `DB_PORT` | Y |  | 数据库服务器的端口。 |
| `DB_USER` | Y |  | 数据库的用户。 |
| `DB_PASSWORD` | Y |  | 数据库用户的密码。 |
| `DB_DATABASE` | Y |  | 数据库服务器上要连接的数据库。 |
| `DB_SCHEMA` | Y |  | 用于数据源的数据库模式。在PostgreSQL中，这将是 `public` 除非为服务显式地制定了模式。 |
| `JWT_SECRET` | Y |  | JWT令牌的对称签名密钥。 |
| `JWT_ISSUER` | Y |  | JWT令牌的发行者。 |

### 建立 `DataSource`

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

```typescript
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`](https://www.npmjs.com/package/db-migrate) 与 [`db-migrate-pg`](https://www.npmjs.com/package/db-migrate-pg) 驱动程序，因此您必须安装这些包才能使用自动迁移。请注意，如果您正在使用一些预先存在的迁移或数据库，它们可能会受到影响。在这种情况下，建议您在项目根目录下复制迁移文件，使用 `FEATURETOGGLE_MIGRATION_COPY` 或者 `SOURCELOOP_MIGRATION_COPY` env变量。您可以根据您的特定需求定制或挑选复制文件中的迁移，然后将它们应用到DB。

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

此外，现在有一个选项可以选择SQL迁移或PostgreSQL迁移。 注：对于 [`@sourceloop/cli`](https://www.npmjs.com/package/@sourceloop/cli?activeTab=readme) 用户可以在搭建过程中通过选择“数据源类型”选项来指定此选项。

### 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规范文档](https://npmcn.com/package/%40sourceloop/feature-toggle-service/openapi.md)

## 常见问题

### @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（1 天前）；至今共发布 101 个版本，其中过去 12 个月发布了 9 个；首次发布于 2021/10/25。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

