NestJS小技巧32-在NestJS应用中使用Unleash实现功能切换的指南

csharp 复制代码
by 雪隐 from https://juejin.cn/user/1433418895994094
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可联系授权

原文链接

在这篇文章中,我将会描述如何使用功能切换在NestJS中控制开发好的API。

介绍

场景非常简单,如果您观察上面的高级架构,客户端应用将使用应用程序暴露的API。在这个流程中,我们可以使用功能切换能力开始限制那些处于实验开发模式的API,使其只对部分客户可用,这样普通可用性(GA)的客户就不会受到这些实验功能的影响。在这篇文章中我将会描述如何创建一个NestJS工程并结合Unleash功能切换来限制API。

安装NestJS

安装NestJS非常简单。您的机器必须事先安装Node然后只要执行下面的命令来全局安装NestJS.

bash 复制代码
npm i -g @nestjs/cli  
nest new project-name (创建一个新的项目)

想要了解更多关于nestjs-cli以及安装的信息请参照 NestJS官网。然后我在基础的代码上做了一些小小的修改。

安装unleash服务

我是Docker的忠实粉丝,因此我选择了基于Docker的Unleash服务器安装。使用下面的docker compose文件来创建您的unleash服务。

bash 复制代码
docker-compose up -d --buil (在dockercompose的同目录下执行这段代码)
yaml 复制代码
# This docker compose setup configures:  
# - the Unleash server instance + the necessary backing Postgres database  
# - the Unleash proxy  
#  
# To learn more about all the parts of Unleash, visit  
# https://docs.getunleash.io  
#  
# NOTE: please do not use this configuration for production setups.  
# Unleash does not take responsibility for any data leaks or other  
# problems that may arise as a result.  
#  
# This is intended to be used for demo, development, and learning  
# purposes only.  
  
version: "3.9"  
services:  
  
  # The Unleash server contains the Unleash configuration and  
  # communicates with server-side SDKs and the Unleash Proxy  
  web:  
    image: unleashorg/unleash-server:latest  
    ports:  
      - "4242:4242"  
    environment:  
      # This points Unleash to its backing database (defined in the `db` section below)  
      DATABASE_URL: "postgres://postgres:unleash@db/postgres"  
      # Disable SSL for database connections. @chriswk: why do we do this?  
      DATABASE_SSL: "false"  
      # Changing log levels:  
      LOG_LEVEL: "warn"  
      # Proxy clients must use one of these keys to connect to the  
      # Proxy. To add more keys, separate them with a comma (`key1,key2`).  
      INIT_FRONTEND_API_TOKENS: "default:development.unleash-insecure-frontend-api-token"  
      # Initialize Unleash with a default set of client API tokens. To  
      # initialize Unleash with multiple tokens, separate them with a  
      # comma (`token1,token2`).  
      INIT_CLIENT_API_TOKENS: "default:development.unleash-insecure-api-token"  
    depends_on:  
      db:  
        condition: service_healthy  
    command: [ "node", "index.js" ]  
    healthcheck:  
      test: wget --no-verbose --tries=1 --spider http://localhost:4242/health || exit 1  
      interval: 1s  
      timeout: 1m  
      retries: 5  
      start_period: 15s  
  db:  
    expose:  
      - "5432"  
    image: postgres:15  
    environment:  
      # create a database called `db`  
      POSTGRES_DB: "db"  
      # trust incoming connections blindly (DON'T DO THIS IN PRODUCTION!)  
      POSTGRES_HOST_AUTH_METHOD: "trust"  
    healthcheck:  
      test:  
        [  
          "CMD",  
          "pg_isready",  
          "--username=postgres",  
          "--host=127.0.0.1",  
          "--port=5432"  
        ]  
      interval: 2s  
      timeout: 1m  
      retries: 5  
      start_period: 10s

实现

现在我有了基本的代码和unleash服务,在我执行之前我需要做一些其他事情,安装一些依赖。

ts 复制代码
yarn add unleash-client @nestjs/config

现在添加一个.env到项目根目录

ini 复制代码
APP_NAME=nestjs-experimental-feature-toggle  
API_KEY=<YOUR SERVER KEY>  
UNLEASH_API_ENDPOINT=http://localhost:4242/api  
METRICS_INTERVAL=1  
REFRESH_INTERVAL=1  
SERVER_PORT=3000

让我们从app.module.ts文件开始。这个文件主要是用来初期化并注入到main.ts文件中去。在这个文件中我注入所有的控制,服务还有像下面这样的其他的模型。ConfigModule.forRoot()将会扫描根目录.env文件,将它的内容加载得到应用中去。

ts 复制代码
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { AppController } from './controllers/app.controller';
import { AppService } from './services/app.service';

@Module({
  imports: [ConfigModule.forRoot()],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

main.ts的内容

ts 复制代码
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as process from 'process';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.SERVER_PORT);
}
bootstrap();

现在让我们来构建服务层app.service.ts。响应内容我先硬编码,如果您们需要的话可以在评论栏中说,我可以创建一个文章模型通过TypeORM来连接到数据库,并返回动态的结果。

ts 复制代码
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  private response = {};
  constructor() {
    this.response['XS'] = '5';
    this.response['S'] = '15';
    this.response['M'] = '25';
    this.response['L'] = '38';
    this.response['XL'] = '28';
    this.response['XXL'] = '15';
  }

  dataAnalytics = (): any => {
    return this.response;
  };
}

是时候来创建控制器app.controller.ts了,有多个部分组成。

constructor:在类中的依赖注入需要使用到它。

init:初始化Unleash客户端

dataAnalytics:根据我决定做什么来验证切换开关的状态

ts 复制代码
import { Controller, Get, Logger } from '@nestjs/common';
import { AppService } from '../services/app.service';
import { startUnleash, Unleash } from 'unleash-client';
import { ConfigService } from '@nestjs/config';

@Controller('/api/v1')
export class AppController {
  private unleash: Unleash;
  private readonly logger: Logger = new Logger(AppController.name);

  constructor(
    private readonly appService: AppService,
    private readonly configService: ConfigService,
  ) {
    this.init();
  }

  private init = async (): Promise<void> => {
    this.unleash = await startUnleash({
      url: this.configService.get<string>('UNLEASH_API_ENDPOINT'),
      appName: 'beta-api',
      metricsInterval: parseInt(this.configService.get('METRICS_INTERVAL'), 10),
      refreshInterval: parseInt(this.configService.get('REFRESH_INTERVAL'), 10),
      customHeaders: {
        Authorization: this.configService.get<string>('API_KEY'),
      },
    });
  };

  @Get('/analytics')
  dataAnalytics(): any {
    // Unleash SDK has now fresh state from the unleash-api
    const isEnabled: boolean = this.unleash.isEnabled('beta-api');
    this.logger.log(`feature switch "beta-api" is ${isEnabled}`);
    if (isEnabled) {
      return this.appService.dataAnalytics();
    } else {
      return {
        response: 'can not access this api as its in experimental mode',
      };
    }
  }
}

现在都完成了,我只要运行应用就行了,首先,我们需要在Unleash中创建一个功能切换,通过URL访问Unleash的网络控制台:http://localhost:4242,点击默认项目并创建一个新的切换,然后为我们的切换添加策略。在这种情况下,我选择了逐步推出策略。一旦您创建了功能切换,然后转到项目设置并创建一个项目访问令牌(创建一个服务器端访问令牌)。

网络控制台应该看上去像下面这样

执行下面的代码并察看结果

bash 复制代码
yarn start:dev

选一个任何您喜欢的API测试工具比如postman或者其他的。现在让我们通过切换来测试这些api看看应用程序会有哪些行为。

结论:

实际的使用场景在文章开始的架构中描述。我们实现了其中的一小部分,这次我们使用了Nestjs框架。与原生的Nodejs和express相比,我个人非常喜欢Nestjs。整个代码库都提供在我的gitee账户上,请克隆并玩一玩。请通过鼓掌和订阅来支持我。祝您学得愉快。

本章代码

代码

相关推荐
susu10830189111 分钟前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿1 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡2 小时前
commitlint校验git提交信息
前端
虾球xz3 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇3 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒3 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员3 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐3 小时前
前端图像处理(一)
前端
程序猿阿伟3 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒3 小时前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript