first commit
This commit is contained in:
513
basic_utils/basic_config.md
Normal file
513
basic_utils/basic_config.md
Normal file
@@ -0,0 +1,513 @@
|
||||
# Basic Config - 基础配置管理模块文档
|
||||
|
||||
## 模块概述
|
||||
|
||||
`basic_config` 是 OneApp 基础工具模块群中的配置管理模块,提供了应用配置的统一管理、API服务管控、版本控制等功能。该模块采用领域驱动设计(DDD)架构,支持动态配置更新、服务白名单管理和API访问控制。
|
||||
|
||||
### 基本信息
|
||||
- **模块名称**: basic_config
|
||||
- **模块路径**: oneapp_basic_utils/basic_config
|
||||
- **类型**: Flutter Package Module
|
||||
- **架构模式**: DDD (Domain Driven Design)
|
||||
- **主要功能**: 配置管理、API服务管控、版本管理
|
||||
|
||||
### 核心特性
|
||||
- **API服务管控**: 基于正则表达式的API路径匹配和访问控制
|
||||
- **服务白名单**: 支持白名单机制,允许特定服务绕过管控
|
||||
- **动态配置更新**: 支持运行时更新服务规则列表
|
||||
- **版本管理**: 内置版本比较和管理功能
|
||||
- **缓存优化**: 使用LRU缓存提升查询性能
|
||||
- **项目隔离**: 支持多项目代码隔离的配置管理
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
basic_config/
|
||||
├── lib/
|
||||
│ ├── basic_config.dart # 模块入口文件
|
||||
│ └── src/
|
||||
│ ├── constants/ # 常量定义
|
||||
│ │ └── module_constant.dart
|
||||
│ ├── dependency/ # 依赖注入
|
||||
│ │ └── i_config_deps.dart
|
||||
│ ├── domains/ # 领域层
|
||||
│ │ ├── basic_config_facade.dart # 配置门面服务
|
||||
│ │ ├── entities/ # 实体对象
|
||||
│ │ │ ├── config_service_failures.dart
|
||||
│ │ │ ├── config_versions.dart
|
||||
│ │ │ └── project_services.dart
|
||||
│ │ ├── interfaces/ # 接口定义
|
||||
│ │ │ └── app_api_services_interface.dart
|
||||
│ │ └── value_objects/ # 值对象
|
||||
│ │ └── project_code.dart
|
||||
│ └── infrastructure/ # 基础设施层
|
||||
│ └── repositories/
|
||||
│ └── app_api_seervices_repository.dart
|
||||
└── pubspec.yaml # 依赖配置
|
||||
```
|
||||
|
||||
## 核心架构组件
|
||||
|
||||
### 1. 版本管理 (Version)
|
||||
|
||||
提供语义化版本号的解析和比较功能:
|
||||
|
||||
```dart
|
||||
mixin Version {
|
||||
/// 转成字符串格式
|
||||
String get toStr => '$major.$minor.$revision';
|
||||
|
||||
/// 版本比较 - 大于
|
||||
bool greaterThan(Version other) {
|
||||
if (major > other.major) return true;
|
||||
if (minor > other.minor && major == other.major) return true;
|
||||
if (revision > other.revision &&
|
||||
major == other.major &&
|
||||
minor == other.minor) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 主版本号
|
||||
int get major;
|
||||
/// 次版本号
|
||||
int get minor;
|
||||
/// 修订版本号
|
||||
int get revision;
|
||||
|
||||
@override
|
||||
String toString() => toStr;
|
||||
|
||||
/// 解析版本字符串 (格式: x.x.x)
|
||||
static Version parseFrom(String versionStr) {
|
||||
final split = versionStr.split('.');
|
||||
if (split.length != 3) {
|
||||
throw UnsupportedError('parse version From $versionStr failed');
|
||||
}
|
||||
|
||||
final int major = int.parse(split[0]);
|
||||
final int minor = int.parse(split[1]);
|
||||
final int revision = int.parse(split[2]);
|
||||
|
||||
return _VersionImpl(major, minor, revision);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 项目服务实体 (ProjectServicesDo)
|
||||
|
||||
定义单个项目的服务配置信息:
|
||||
|
||||
```dart
|
||||
class ProjectServicesDo {
|
||||
/// 构造函数
|
||||
/// [projectCode] 项目编号
|
||||
/// [ruleList] api path 正则规则
|
||||
/// [disableServiceList] 下架的服务列表
|
||||
ProjectServicesDo({
|
||||
required this.projectCode,
|
||||
required this.ruleList,
|
||||
required this.disableServiceList,
|
||||
}) : _ruleListRegex = ruleList.map(RegExp.new).toList(growable: false);
|
||||
|
||||
/// 项目编号
|
||||
final ProjectCodeVo projectCode;
|
||||
|
||||
/// 该项目对应的规则列表
|
||||
final List<String> ruleList;
|
||||
|
||||
/// 对应正则表达式
|
||||
final List<RegExp> _ruleListRegex;
|
||||
|
||||
/// 下架的服务
|
||||
final List<String> disableServiceList;
|
||||
|
||||
/// 检查路径是否匹配规则
|
||||
bool isMatchBy(String s) {
|
||||
bool match = false;
|
||||
for (final rule in _ruleListRegex) {
|
||||
match = rule.hasMatch(s);
|
||||
if (match) break;
|
||||
}
|
||||
return match;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 应用项目管理 (AppProjectsDo)
|
||||
|
||||
管理所有项目的服务配置:
|
||||
|
||||
```dart
|
||||
class AppProjectsDo {
|
||||
/// 构造函数
|
||||
AppProjectsDo(this.version, this.projects) {
|
||||
for (final project in projects) {
|
||||
_projectsMap[project.projectCode.id] = project;
|
||||
}
|
||||
}
|
||||
|
||||
/// 版本号
|
||||
final int version;
|
||||
|
||||
/// app所有项目的信息
|
||||
List<ProjectServicesDo> projects;
|
||||
|
||||
/// 项目映射表
|
||||
final Map<String, ProjectServicesDo> _projectsMap = {};
|
||||
|
||||
/// 根据项目代码查找项目
|
||||
ProjectServicesDo? findBy(String projectCode) => _projectsMap[projectCode];
|
||||
|
||||
/// 检查服务是否已下架
|
||||
bool isServiceDisabled({
|
||||
required String projectCode,
|
||||
required String service,
|
||||
}) {
|
||||
try {
|
||||
final project = _projectsMap[projectCode];
|
||||
project!.disableServiceList.firstWhere((e) => e == service);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取所有项目编号
|
||||
List<String> getProjectCodes() => _projectsMap.keys.toList(growable: false);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 基础配置门面 (BasicConfigFacade)
|
||||
|
||||
核心配置管理服务,采用单例模式:
|
||||
|
||||
```dart
|
||||
abstract class IBasicConfigFacade {
|
||||
/// 初始化配置
|
||||
Future<Either<ConfigServiceFailures, Unit>> initialize({
|
||||
required String versionOfConnectivity,
|
||||
String jsonServiceList = '',
|
||||
List<String> whiteServiceList = const [],
|
||||
IBasicConfigDeps? deps,
|
||||
});
|
||||
|
||||
/// 检查API是否命中管控规则
|
||||
Either<ConfigServiceFailures, bool> queryApiIfHit({
|
||||
String projectCode = '',
|
||||
String url = '',
|
||||
});
|
||||
|
||||
/// 检查API是否在白名单
|
||||
bool queryApiIfInWhiteList({required String url});
|
||||
|
||||
/// 主动更新服务规则列表
|
||||
Future<bool> updateServiceList({List<String> projectCodes = const []});
|
||||
|
||||
/// 检查服务是否下架
|
||||
bool isServiceDisabled({
|
||||
required String projectCode,
|
||||
required String service,
|
||||
});
|
||||
|
||||
/// 根据项目代码查询项目信息
|
||||
Either<ConfigServiceFailures, ProjectServicesDo> queryProjectBy({
|
||||
String projectCode = '',
|
||||
});
|
||||
|
||||
/// 获取当前连接版本
|
||||
Version get currConnVersion;
|
||||
}
|
||||
|
||||
/// 全局配置对象
|
||||
IBasicConfigFacade basicConfigFacade = BasicConfigFacadeImpl();
|
||||
```
|
||||
|
||||
### 5. 具体实现 (BasicConfigFacadeImpl)
|
||||
|
||||
```dart
|
||||
class BasicConfigFacadeImpl implements IBasicConfigFacade {
|
||||
BasicConfigFacadeImpl({IAppApiServiceRepo? appApiServiceRepo})
|
||||
: _apiServiceRepo = appApiServiceRepo ?? ApiServiceListRepository();
|
||||
|
||||
static const String _tag = 'BasicConfigFacadeImpl';
|
||||
|
||||
final IAppApiServiceRepo _apiServiceRepo;
|
||||
IBasicConfigDeps _deps = const DefaultConfigDeps();
|
||||
final _cache = LruCache<String, bool>(storage: InMemoryStorage(20));
|
||||
late Version _connVersion;
|
||||
|
||||
@override
|
||||
Future<Either<ConfigServiceFailures, Unit>> initialize({
|
||||
required String versionOfConnectivity,
|
||||
String jsonServiceList = '',
|
||||
List<String> whiteServiceList = const [],
|
||||
IBasicConfigDeps? deps,
|
||||
}) async {
|
||||
if (deps != null) _deps = deps;
|
||||
_connVersion = Version.parseFrom(versionOfConnectivity);
|
||||
|
||||
// 初始化api管控配置列表
|
||||
final r = await _apiServiceRepo.initialize(
|
||||
deps: _deps,
|
||||
jsonServiceList: jsonServiceList,
|
||||
whiteServiceList: whiteServiceList,
|
||||
);
|
||||
|
||||
return r ? right(unit) : left(ConfigServiceFailures(
|
||||
errorCodeConfigServiceInvalidLocalServiceList,
|
||||
'initialize failed',
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
Either<ConfigServiceFailures, bool> queryApiIfHit({
|
||||
String projectCode = '',
|
||||
String url = '',
|
||||
}) {
|
||||
final appProject = _apiServiceRepo.appProject;
|
||||
if (appProject == null) {
|
||||
return left(ConfigServiceFailures(
|
||||
errorCodeConfigServiceEmptyServiceList,
|
||||
'empty service list',
|
||||
));
|
||||
}
|
||||
|
||||
final findBy = appProject.findBy(projectCode);
|
||||
if (findBy == null) return right(false);
|
||||
|
||||
// 使用缓存优化查询性能
|
||||
final hitCache = _cache.get(url);
|
||||
if (hitCache == null) {
|
||||
final matchBy = findBy.isMatchBy(url);
|
||||
_cache.set(url, matchBy);
|
||||
return right(matchBy);
|
||||
}
|
||||
|
||||
return right(hitCache);
|
||||
}
|
||||
|
||||
// 其他方法实现...
|
||||
}
|
||||
```
|
||||
|
||||
## 使用指南
|
||||
|
||||
### 1. 初始化配置
|
||||
|
||||
```dart
|
||||
import 'package:basic_config/basic_config.dart';
|
||||
|
||||
// 初始化基础配置
|
||||
await basicConfigFacade.initialize(
|
||||
versionOfConnectivity: '1.0.0',
|
||||
jsonServiceList: jsonConfigData,
|
||||
whiteServiceList: ['api/health', 'api/version'],
|
||||
);
|
||||
```
|
||||
|
||||
### 2. API访问控制
|
||||
|
||||
```dart
|
||||
// 检查API是否命中管控规则
|
||||
final result = basicConfigFacade.queryApiIfHit(
|
||||
projectCode: 'oneapp_main',
|
||||
url: '/api/user/profile',
|
||||
);
|
||||
|
||||
result.fold(
|
||||
(failure) => print('查询失败: ${failure.message}'),
|
||||
(isHit) => {
|
||||
if (isHit) {
|
||||
print('API被管控,需要特殊处理')
|
||||
} else {
|
||||
print('API正常访问')
|
||||
}
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### 3. 白名单检查
|
||||
|
||||
```dart
|
||||
// 检查API是否在白名单
|
||||
bool inWhiteList = basicConfigFacade.queryApiIfInWhiteList(
|
||||
url: '/api/health'
|
||||
);
|
||||
|
||||
if (inWhiteList) {
|
||||
// 白名单API,直接放行
|
||||
print('白名单API,允许访问');
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 服务状态检查
|
||||
|
||||
```dart
|
||||
// 检查服务是否下架
|
||||
bool isDisabled = basicConfigFacade.isServiceDisabled(
|
||||
projectCode: 'oneapp_main',
|
||||
service: 'user_profile',
|
||||
);
|
||||
|
||||
if (isDisabled) {
|
||||
// 服务已下架,显示维护页面
|
||||
showMaintenancePage();
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 动态更新配置
|
||||
|
||||
```dart
|
||||
// 更新服务规则列表
|
||||
bool updateSuccess = await basicConfigFacade.updateServiceList(
|
||||
projectCodes: ['oneapp_main', 'oneapp_car'],
|
||||
);
|
||||
|
||||
if (updateSuccess) {
|
||||
print('配置更新成功');
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 版本管理
|
||||
|
||||
```dart
|
||||
// 版本解析和比较
|
||||
Version currentVersion = Version.parseFrom('1.2.3');
|
||||
Version newVersion = Version.parseFrom('1.2.4');
|
||||
|
||||
if (newVersion.greaterThan(currentVersion)) {
|
||||
print('发现新版本: ${newVersion.toStr}');
|
||||
// 执行更新逻辑
|
||||
}
|
||||
```
|
||||
|
||||
## 配置文件格式
|
||||
|
||||
### 服务配置JSON格式
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"projects": [
|
||||
{
|
||||
"projectCode": "oneapp_main",
|
||||
"ruleList": [
|
||||
"^/api/user/.*",
|
||||
"^/api/payment/.*"
|
||||
],
|
||||
"disableServiceList": [
|
||||
"old_payment_service",
|
||||
"deprecated_user_api"
|
||||
]
|
||||
},
|
||||
{
|
||||
"projectCode": "oneapp_car",
|
||||
"ruleList": [
|
||||
"^/api/vehicle/.*",
|
||||
"^/api/charging/.*"
|
||||
],
|
||||
"disableServiceList": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 依赖配置
|
||||
|
||||
### pubspec.yaml 关键依赖
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
# 函数式编程支持
|
||||
dartz: ^0.10.1
|
||||
|
||||
# 基础日志模块
|
||||
basic_logger:
|
||||
path: ../basic_logger
|
||||
|
||||
# 基础存储模块
|
||||
basic_storage:
|
||||
path: ../basic_storage
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
```
|
||||
|
||||
## 架构设计原则
|
||||
|
||||
### 1. DDD分层架构
|
||||
- **Domain层**: 包含业务实体、值对象和领域服务
|
||||
- **Infrastructure层**: 处理数据持久化和外部服务调用
|
||||
- **Application层**: 通过Facade模式提供应用服务
|
||||
|
||||
### 2. 函数式编程
|
||||
- 使用`dartz`包提供的`Either`类型处理错误
|
||||
- 避免异常抛出,通过类型系统表达可能的失败情况
|
||||
|
||||
### 3. 依赖注入
|
||||
- 通过接口定义依赖,支持测试替换
|
||||
- 使用抽象类定义服务边界
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 1. 缓存策略
|
||||
- 使用LRU缓存存储API匹配结果
|
||||
- 缓存大小限制为20个条目,避免内存过度使用
|
||||
|
||||
### 2. 正则表达式优化
|
||||
- 预编译正则表达式,避免重复编译开销
|
||||
- 使用不可变列表存储编译后的正则
|
||||
|
||||
### 3. 查询优化
|
||||
- 使用Map结构优化项目查找性能
|
||||
- 短路求值减少不必要的匹配操作
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 错误处理
|
||||
```dart
|
||||
// 推荐:使用Either处理可能的错误
|
||||
final result = basicConfigFacade.queryApiIfHit(
|
||||
projectCode: projectCode,
|
||||
url: url,
|
||||
);
|
||||
|
||||
result.fold(
|
||||
(failure) => handleFailure(failure),
|
||||
(success) => handleSuccess(success),
|
||||
);
|
||||
|
||||
// 不推荐:使用try-catch
|
||||
try {
|
||||
final result = riskyOperation();
|
||||
handleSuccess(result);
|
||||
} catch (e) {
|
||||
handleError(e);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 配置管理
|
||||
- 在应用启动时初始化配置
|
||||
- 定期检查和更新远程配置
|
||||
- 为关键服务提供降级策略
|
||||
|
||||
### 3. 测试策略
|
||||
- 使用依赖注入进行单元测试
|
||||
- 模拟网络请求测试异常情况
|
||||
- 验证缓存行为的正确性
|
||||
|
||||
## 问题排查
|
||||
|
||||
### 常见问题
|
||||
1. **初始化失败**: 检查配置JSON格式和依赖注入设置
|
||||
2. **正则匹配异常**: 验证规则列表中的正则表达式语法
|
||||
3. **缓存不生效**: 确认URL格式一致性
|
||||
|
||||
### 调试技巧
|
||||
- 启用详细日志查看配置加载过程
|
||||
- 使用`basicConfigTag`过滤相关日志
|
||||
- 检查版本解析是否符合x.x.x格式
|
||||
Reference in New Issue
Block a user