Files
oneapp_docs/basic_utils/basic_config.md
2025-09-24 14:08:54 +08:00

514 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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格式