swagger_generator_flutter/docs/USAGE_GUIDE.md

16 KiB
Raw Permalink Blame History

使用指南与最佳实践

🚀 快速开始

环境准备

  1. 确保 Dart/Flutter 环境
dart --version  # 确保 Dart >= 3.0
flutter --version  # 确保 Flutter >= 3.0
  1. 安装项目依赖
cd your_flutter_project
flutter pub get
  1. 准备 OpenAPI 文档
  • 确保有有效的 swagger.jsonopenapi.json 文件
  • 建议使用 OpenAPI 3.0 格式

基础使用

在项目根目录下(generator_config.yaml 所在目录)运行以下命令:

# 步骤 1: 生成 API 定义和 Freezed 模型
# 这会根据 swagger.json 生成 *.dart 文件,但它们还不完整
dart run swagger_generator_flutter generate --all

# 步骤 2: 运行 build_runner 完成代码生成
# 这会生成 *.freezed.dart 和 *.g.dart 文件,补全模型和序列化逻辑
dart run build_runner build --delete-conflicting-outputs

编程方式 (推荐进阶用户)

import 'dart:io';
import 'package:swagger_generator_flutter/swagger_generator_flutter.dart';

void main() async {
  // 1. 创建解析器
  final parser = PerformanceParser(
    config: ParseConfig(
      enablePerformanceStats: true,
      enableCaching: true,
    ),
  );

  // 2. 解析文档
  final jsonString = await File('swagger.json').readAsString();
  final document = await parser.parseDocument(jsonString);

  // 3. 创建生成器
  final generator = RetrofitApiGenerator(
    className: 'ApiService',
    splitByTags: true,
  );

  // 4. 生成并保存代码
  final code = generator.generateFromDocument(document);
  await File('lib/api/api_service.dart').writeAsString(code);
  
  print('✅ 代码生成完成!');
}

🏗️ 项目集成

1. 依赖配置

在你的 Flutter 项目的 pubspec.yaml 中添加必要依赖:

dependencies:
  # 网络请求
  dio: ^5.4.0
  retrofit: ^4.0.0

  # Freezed 模型
  freezed_annotation: ^2.4.1
  json_annotation: ^4.8.1

dev_dependencies:
  # 代码生成
  build_runner: ^2.4.7
  retrofit_generator: ^8.0.0
  json_serializable: ^6.7.1
  freezed: ^2.4.7

2. 项目结构

推荐的项目结构:

your_flutter_project/
├── lib/
│   ├── api/
│   │   ├── generated/          # 生成的 API 文件
│   │   │   ├── api_service.dart
│   │   │   ├── user_api.dart
│   │   │   └── order_api.dart
│   │   ├── models/             # 生成的模型文件
│   │   │   ├── user.dart
│   │   │   ├── order.dart
│   │   │   └── index.dart
│   │   ├── config/             # API 配置
│   │   │   ├── api_config.dart
│   │   │   └── dio_config.dart
│   │   └── interceptors/       # 拦截器
│   │       ├── auth_interceptor.dart
│   │       └── error_interceptor.dart
│   ├── services/               # 业务服务层
│   └── ...
├── swagger.json                # OpenAPI 文档
└── generator_config.yaml       # 生成器配置

3. 配置文件

创建 generator_config.yaml

# 生成器配置
generator:
  className: "ApiService"
  outputDir: "lib/api/generated"
  generateModularApis: true
  generateBaseResult: true
  generatePagination: true
  generateFileUpload: true
  
# 类型映射
typeMapping:
  "integer": "int"
  "number": "double"
  "boolean": "bool"
  
# 排除的标签
excludeTags:
  - "Internal"
  - "Debug"
  
# 自定义模板
templates:
  baseResultType: "ApiResult"
  pageResultType: "PagedResult"

📝 最佳实践

1. OpenAPI 文档规范

推荐的文档结构

{
  "openapi": "3.0.1",
  "info": {
    "title": "Your API",
    "version": "v1",
    "description": "API description"
  },
  "servers": [
    {
      "url": "https://api.yourdomain.com",
      "description": "Production server"
    }
  ],
  "components": {
    "schemas": {
      "BaseResult": {
        "type": "object",
        "properties": {
          "success": {"type": "boolean"},
          "message": {"type": "string"},
          "data": {"type": "object"}
        }
      },
      "User": {
        "type": "object",
        "required": ["id", "username"],
        "properties": {
          "id": {"type": "integer"},
          "username": {"type": "string"},
          "email": {"type": "string", "nullable": true}
        }
      }
    }
  }
}

避免的常见问题

// 不要:缺少 schema 定义
{
  "responses": {
    "200": {
      "description": "Success"
      // 缺少 content 和 schema
    }
  }
}

// 不要:模糊的类型定义
{
  "properties": {
    "data": {"type": "object"}  // 应该明确定义结构
  }
}

// 不要:不一致的命名
{
  "paths": {
    "/getUsers": {},      // 应该用 RESTful 风格
    "/user/create": {}    // 应该是 POST /users
  }
}

2. 代码生成最佳实践

配置合适的解析器

// 开发环境 - 详细统计
final parser = PerformanceParser(
  config: ParseConfig(
    enablePerformanceStats: true,
    enableDebugMode: true,
    logLevel: LogLevel.debug,
  ),
);

// 生产环境 - 高性能
final parser = PerformanceParser(
  config: ParseConfig(
    enableParallelParsing: true,
    enableCaching: true,
    maxConcurrency: 4,
    enableMemoryOptimization: true,
  ),
);

3. 错误处理策略

分层错误处理

class ApiService {
  final Dio _dio;
  
  ApiService(this._dio) {
    _setupInterceptors();
  }
  
  void _setupInterceptors() {
    // 请求拦截器
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        // 添加认证头
        options.headers['Authorization'] = 'Bearer $token';
        handler.next(options);
      },
      onError: (error, handler) {
        // 统一错误处理
        final apiError = _handleError(error);
        handler.reject(DioException(
          requestOptions: error.requestOptions,
          error: apiError,
        ));
      },
    ));
  }
  
  ApiError _handleError(DioException error) {
    switch (error.response?.statusCode) {
      case 401:
        return ApiError.unauthorized();
      case 403:
        return ApiError.forbidden();
      case 404:
        return ApiError.notFound();
      case 500:
        return ApiError.serverError();
      default:
        return ApiError.unknown(error.message);
    }
  }
}

业务层错误处理

class UserService {
  final UserApi _userApi;
  
  UserService(this._userApi);
  
  Future<Result<User>> getUser(int userId) async {
    try {
      final response = await _userApi.getUser(userId);
      if (response.success) {
        return Result.success(response.data!);
      } else {
        return Result.failure(response.message ?? 'Unknown error');
      }
    } on ApiError catch (e) {
      return Result.failure(e.message);
    } catch (e) {
      return Result.failure('Network error: $e');
    }
  }
}

4. 性能优化

缓存策略

// 配置智能缓存
final cache = SmartCache<String>(
  maxSize: 1000,
  strategy: CacheStrategy.smart,
  defaultTtl: Duration(minutes: 30),
);

// 使用缓存包装 API 调用
class CachedApiService {
  final ApiService _apiService;
  final SmartCache<String> _cache;
  
  Future<BaseResult<User>> getUser(int userId) async {
    final cacheKey = 'user_$userId';
    
    // 尝试从缓存获取
    final cached = _cache.get(cacheKey);
    if (cached != null) {
      return BaseResult.fromJson(jsonDecode(cached));
    }
    
    // 从 API 获取
    final result = await _apiService.getUser(userId);
    
    // 缓存结果
    if (result.success) {
      _cache.put(cacheKey, jsonEncode(result.toJson()));
    }
    
    return result;
  }
}

并发控制

class ApiService {
  final Semaphore _semaphore = Semaphore(3); // 限制并发数
  
  Future<T> _executeWithLimit<T>(Future<T> Function() operation) async {
    await _semaphore.acquire();
    try {
      return await operation();
    } finally {
      _semaphore.release();
    }
  }
  
  Future<List<User>> getUsers(List<int> userIds) async {
    final futures = userIds.map((id) => 
      _executeWithLimit(() => getUser(id))
    );
    
    return Future.wait(futures);
  }
}

🔧 高级配置

1. 自定义生成器

class CustomRetrofitGenerator extends BaseGenerator {
  @override
  String generate() {
    final buffer = StringBuffer();
    
    // 自定义文件头
    buffer.writeln('// Custom Generated API');
    buffer.writeln('// Generated at: ${DateTime.now()}');
    
    // 自定义导入
    buffer.writeln("import 'package:dio/dio.dart';");
    buffer.writeln("import 'package:retrofit/retrofit.dart';");
    
    // 生成自定义代码
    _generateCustomMethods(buffer);
    
    return buffer.toString();
  }
  
  void _generateCustomMethods(StringBuffer buffer) {
    // 实现自定义生成逻辑
  }
}

2. 自定义验证规则

class CustomValidationRule extends ValidationRule {
  @override
  String get name => 'CustomRule';
  
  @override
  List<ValidationError> validate(SwaggerDocument document) {
    final errors = <ValidationError>[];
    
    // 检查所有 API 是否有描述
    for (final path in document.paths.values) {
      for (final operation in path.operations.values) {
        if (operation.summary?.isEmpty ?? true) {
          errors.add(ValidationError(
            severity: ErrorSeverity.warning,
            title: 'Missing API description',
            description: 'API ${operation.operationId} lacks description',
            location: operation.operationId,
          ));
        }
      }
    }
    
    return errors;
  }
}

3. 自定义模板

创建自定义模板文件 templates/custom_api.mustache

/// {{title}} API
/// Generated by Custom Generator
class {{className}} {
  final Dio _dio;
  
  {{className}}(this._dio);
  
  {{#operations}}
  /// {{summary}}
  @{{httpMethod}}('{{path}}')
  Future<{{returnType}}> {{methodName}}(
    {{#parameters}}
    @{{paramType}}('{{name}}') {{type}} {{name}},
    {{/parameters}}
  );
  {{/operations}}
}

使用自定义模板:

// 使用自定义生成器时,请继承 BaseGenerator 并实现 generate()
// 或基于 RetrofitApiGenerator 的输出进行二次处理。

🐛 故障排除

常见问题及解决方案

1. 解析失败

问题: SwaggerParseException: Invalid JSON format

解决方案:

# 验证 JSON 格式
jsonlint swagger.json

# 或使用在线工具验证
# https://jsonlint.com/

问题: Reference not found: #/components/schemas/User

解决方案:

// 检查引用是否存在
final validator = EnhancedValidator();
final isValid = validator.validateDocument(document);
final errors = validator.errorReporter.getErrorsBySeverity(ErrorSeverity.error);

for (final error in errors) {
  if (error.title.contains('Reference')) {
    print('缺少引用: ${error.description}');
  }
}

2. 生成错误

问题: 生成的代码包含语法错误

解决方案:

// 启用严格验证
final validator = EnhancedValidator(
  strictMode: true,
  customRules: [
    TypeConsistencyRule(),
    NamingConventionRule(),
  ],
);

// 检查生成前的文档质量
if (!validator.validateDocument(document)) {
  final report = validator.errorReporter.generateReport();
  print('文档质量问题:\n$report');
  return;
}

问题: 生成的类型不存在

解决方案:

// 检查 Schema 定义
final schemas = document.components?.schemas ?? {};
if (!schemas.containsKey('YourType')) {
  print('错误: Schema YourType 不存在');
  print('可用 Schemas: ${schemas.keys.join(', ')}');
}

3. 性能问题

问题: 解析大文档时内存不足

解决方案:

// 启用内存优化
final parser = PerformanceParser(
  config: ParseConfig(
    enableMemoryOptimization: true,
    enableStreamParsing: true,
    maxConcurrency: 2, // 降低并发数
  ),
);

问题: 生成速度慢

解决方案:

// 在 CI 中按模块并行执行多个 RetrofitApiGenerator 任务
final generator = RetrofitApiGenerator(
  className: 'ApiService',
  splitByTags: true,
);

调试技巧

1. 启用详细日志

// 配置日志级别
import 'package:logging/logging.dart';

void setupLogging() {
  Logger.root.level = Level.ALL;
  Logger.root.onRecord.listen((record) {
    print('${record.level.name}: ${record.time}: ${record.message}');
  });
}

// 在解析器中使用
final parser = PerformanceParser(
  config: ParseConfig(
    enableVerboseLogging: true,
    logLevel: LogLevel.debug,
  ),
);

2. 性能分析

// 使用性能监控器
final monitor = PerformanceMonitor();

monitor.startOperation('full_generation');

// 解析阶段
monitor.startOperation('parse');
final document = await parser.parseDocument(jsonString);
monitor.endOperation('parse');

// 验证阶段
monitor.startOperation('validate');
final isValid = validator.validateDocument(document);
monitor.endOperation('validate');

// 生成阶段
monitor.startOperation('generate');
final code = generator.generateFromDocument(document);
monitor.endOperation('generate');

monitor.endOperation('full_generation');

// 输出性能报告
final report = monitor.generateReport();
print(report);

3. 内存分析

// 监控内存使用
import 'dart:developer';

void trackMemoryUsage(String operation) {
  final info = ProcessInfo.currentRss;
  print('$operation - Memory: ${info / 1024 / 1024:.2f}MB');
}

trackMemoryUsage('Before parsing');
final document = await parser.parseDocument(jsonString);
trackMemoryUsage('After parsing');

final code = generator.generateFromDocument(document);
trackMemoryUsage('After generation');

📚 示例项目

完整示例项目结构

example_project/
├── lib/
│   ├── main.dart
│   ├── api/
│   │   ├── generated/
│   │   │   ├── api_service.dart
│   │   │   ├── user_api.dart
│   │   │   └── order_api.dart
│   │   ├── models/
│   │   │   ├── user.dart
│   │   │   ├── order.dart
│   │   │   └── index.dart
│   │   ├── config/
│   │   │   └── api_config.dart
│   │   └── services/
│   │       ├── user_service.dart
│   │       └── order_service.dart
│   ├── ui/
│   │   ├── pages/
│   │   └── widgets/
│   └── utils/
├── swagger.json
├── generator_config.yaml
└── generate_api.dart

生成脚本示例

generate_api.dart:

import 'dart:io';
import 'package:swagger_generator_flutter/swagger_generator_flutter.dart';

Future<void> main() async {
  print('🚀 开始生成 API 代码...');
  
  try {
    // 1. 配置和初始化
    final config = await _loadConfig();
    final parser = _createParser(config);
    final validator = _createValidator(config);
    final generator = _createGenerator(config);
    
    // 2. 解析文档
    print('📖 解析 OpenAPI 文档...');
    final document = await _parseDocument(parser, config.swaggerPath);
    
    // 3. 验证文档
    print('✅ 验证文档...');
    await _validateDocument(validator, document);
    
    // 4. 生成代码
    print('🔧 生成代码...');
    await _generateCode(generator, document, config);
    
    // 5. 后处理
    print('🎯 后处理...');
    await _postProcess(config);
    
    print('✅ API 代码生成完成!');
    
  } catch (e, stackTrace) {
    print('❌ 生成失败: $e');
    print('堆栈跟踪: $stackTrace');
    exit(1);
  }
}

// 实现各个辅助方法...

文档版本: v3.0 最后更新: 2025-11-21 维护者: Max