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账户上,请克隆并玩一玩。请通过鼓掌和订阅来支持我。祝您学得愉快。