Flutter OpenAPI生成插件openapi_generator的使用

发布于 1周前 作者 phonegap100 来自 Flutter

Flutter OpenAPI生成插件openapi_generator的使用

简介

pub package

openapi_generator 是一个用于在Flutter/Dart项目中生成OpenAPI客户端SDK库的工具。通过此库,你可以直接从你的OpenAPI规范文件生成客户端SDK库(详见示例)。

该库需与 openapi-generator-annotations 一起使用。

要求

  1. Java:你必须在系统上安装Java才能使此库工作。如果你是开发者,很可能已经安装了Java。指导如何安装Java超出了本项目的范围。
  2. 互联网连接:仅用于首次下载OpenAPI jar包。一旦缓存,之后无需网络连接。

使用方法

添加依赖

pubspec.yaml文件中的dependencies部分添加以下内容:

dependencies:
  openapi_generator_annotations: ^latest

在dev_dependencies部分添加以下内容:

dev_dependencies:
  openapi_generator: ^latest

注解类

使用@Openapi()注解任意Dart类,例如:

import 'package:openapi_generator_annotations/openapi_generator_annotations.dart';

@Openapi(
   additionalProperties:
   DioProperties(pubName: 'petstore_api', pubAuthor: 'Johnny dep..'),
   inputSpec:
   RemoteSpec(path: 'https://petstore3.swagger.io/api/v3/openapi.json'),
   typeMappings: {'Pet': 'ExamplePet'},
   generatorName: Generator.dio,
   runSourceGenOnOutput: true,
   outputDirectory: 'api/petstore_api',
)
class Example {}

生成代码

运行以下命令以根据注解中指定的规范文件生成OpenAPI客户端SDK:

flutter pub run build_runner build --delete-conflicting-outputs

生成的API SDK将出现在注解中指定的文件夹中。

新增功能 (6.0版本及以后)

  • skipIfSpecUnchanged: 设置为false以每次生成客户端SDK,即使OpenAPI规范没有变化,默认值为true
  • forceAlwaysRun(重大变更): 强制build_runner通过标记注解文件来检测更改。可能会导致团队环境中出现合并冲突,默认值为false

示例Demo

下面是一个完整的示例,演示如何使用openapi_generator生成一个简单的API客户端。

创建新Flutter项目

首先,创建一个新的Flutter项目:

flutter create flutter_openapi_demo
cd flutter_openapi_demo

更新pubspec.yaml

更新pubspec.yaml文件,添加必要的依赖项:

dependencies:
  openapi_generator_annotations: ^latest

dev_dependencies:
  openapi_generator: ^latest
  build_runner: ^latest

创建示例类

lib/目录下创建一个名为example.dart的文件,并添加以下内容:

// example/example.dart
import 'package:openapi_generator_annotations/openapi_generator_annotations.dart';

@Openapi(
  additionalProperties:
      DioProperties(pubName: 'petstore_api', pubAuthor: 'Your Name'),
  inputSpec: RemoteSpec(path: 'https://petstore3.swagger.io/api/v3/openapi.json'),
  generatorName: Generator.dio,
  outputDirectory: 'api/petstore_api',
)
class PetStoreApi {}

生成API客户端

运行以下命令以生成API客户端:

flutter pub run build_runner build --delete-conflicting-outputs

使用生成的API客户端

lib/main.dart中使用生成的API客户端:

import 'package:flutter/material.dart';
import 'package:petstore_api/petstore_api.dart'; // 导入生成的API客户端

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter OpenAPI Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter OpenAPI Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<dynamic>? pets;

  void _fetchPets() async {
    final api = PetApi();
    try {
      final response = await api.findPetsByStatus(status: ['available']);
      setState(() {
        pets = response;
      });
    } catch (e) {
      print('Error fetching pets: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: _fetchPets,
              child: Text('Fetch Pets'),
            ),
            if (pets != null && pets!.isNotEmpty)
              Expanded(
                child: ListView.builder(
                  itemCount: pets!.length,
                  itemBuilder: (context, index) {
                    final pet = pets![index];
                    return ListTile(
                      title: Text(pet['name']),
                      subtitle: Text(pet['status']),
                    );
                  },
                ),
              ),
          ],
        ),
      ),
    );
  }
}

运行应用

确保你已经启动了一个模拟器或连接了一台设备,然后运行应用:

flutter run

现在,你应该能够看到一个按钮,点击后会从Petstore API获取宠物列表并显示在界面上。

已知问题

依赖问题/冲突

如果遇到依赖冲突问题,可以使用dependency_overrides来解决。例如,在生成的pubspec.yaml中添加以下内容:

dependency_overrides:
  analyzer: <-- preferred version -->

同时,在.openapi-generator-ignore中添加pubspec.yaml以防止其被覆盖。

解决生成代码中的问题

  1. 修正OpenAPI文档:检查并修正可能导致问题的OpenAPI文档。
  2. 手动修正生成代码:如果无法修正OpenAPI文档,可以手动修正生成的代码,并将其添加到.openapi-generator-ignore文件中以防止下次生成时被覆盖。

常见问题解答

  • Q: 如何防止某些文件被生成(例如测试文件)?
    • A: 将这些文件添加到.openapi-generator-ignore文件中,例如添加test/*以防止生成测试文件。

功能和Bug

请在 GitHub Issues 中提交功能请求和Bug报告。


希望这个指南能帮助你顺利使用openapi_generator生成API客户端。如果有任何问题或建议,请随时联系我!


更多关于Flutter OpenAPI生成插件openapi_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter OpenAPI生成插件openapi_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于Flutter中如何使用openapi_generator插件来根据OpenAPI规范(通常称为Swagger文档)生成客户端代码,这里是一个具体的代码案例展示。

环境准备

首先,确保你的Flutter开发环境已经设置好,并且已经安装了必要的依赖。你需要有Flutter SDK和一个支持Flutter开发的IDE(如VSCode或Android Studio)。

安装openapi_generator

在你的Flutter项目的根目录下,打开命令行工具并运行以下命令来添加openapi_generator依赖到你的pubspec.yaml文件中:

flutter pub add openapi_generator

配置openapi_generator

接下来,你需要一个OpenAPI规范文件(通常是JSON或YAML格式)。假设你有一个名为api.yaml的OpenAPI规范文件。

在你的Flutter项目根目录下创建一个名为openapi_generator_config.yaml的配置文件,内容如下:

generator_name: flutter
input_spec: path/to/your/api.yaml  # 替换为你的OpenAPI规范文件的实际路径
output_dir: lib/generated  # 输出生成的代码到这个目录
template_dir: null
additional_properties:
  hide_namespace: true
  hide_generation_timestamp: true

生成代码

现在,你可以使用openapi_generator命令行工具来生成代码。在命令行中运行以下命令:

flutter pub run openapi_generator:generate

这条命令会根据openapi_generator_config.yaml中的配置生成客户端代码到指定的lib/generated目录。

使用生成的代码

生成的代码通常包括API服务、数据模型等。你可以在Flutter应用中使用这些生成的代码来调用API。

以下是一个简单的示例,展示如何使用生成的API服务:

import 'package:flutter/material.dart';
import 'package:your_app_name/generated/api.dart';  // 导入生成的API代码
import 'package:your_app_name/generated/models.dart';  // 导入生成的数据模型

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('OpenAPI Client Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              // 创建API客户端实例
              final apiClient = ApiClient();
              
              // 使用生成的API服务调用端点
              try {
                final response = await apiClient.defaultApi.yourEndpoint(yourRequestParams);
                // 处理响应
                print(response);
              } catch (e) {
                // 处理错误
                print('Error: $e');
              }
            },
            child: Text('Call API'),
          ),
        ),
      ),
    );
  }
}

在上面的代码中,ApiClient是生成的API客户端类,defaultApi是生成的API服务类,yourEndpoint是OpenAPI规范中定义的一个端点方法,yourRequestParams是调用该端点所需的参数(根据生成的代码调整)。

注意事项

  1. 路径调整:确保openapi_generator_config.yaml中的input_spec路径正确指向你的OpenAPI规范文件。
  2. 命名冲突:如果生成的代码与你的现有代码有命名冲突,可能需要手动调整。
  3. API更新:当OpenAPI规范发生变化时,记得重新运行openapi_generator来生成新的代码。

通过这种方式,你可以利用openapi_generator插件快速根据OpenAPI规范生成Flutter客户端代码,从而简化API集成的流程。

回到顶部