Flutter API文档生成插件swagger_generator的使用
Flutter API文档生成插件swagger_generator的使用
swagger_generator
是一个利用 dio 拦截器自动生成 swagger 结构的库。使用它能够轻松地创建 API 文档,减少工作量。
特性
- 库的模型基于 Swagger 基本结构。
- 自动创建 swagger 路径、标签、请求体、请求响应等,并保存到
swagger.json
文件中。 - 可以预览
swagger.json
文件。 - 自动保存到本地并合并更新过的请求/响应数据。
- 同步数据到 GitLab 以便在 Swagger Hub 中查看。
- 库会忽略基础 URL 在
servers
之外的请求。
入门指南
配置拦截器
将此库添加到 dio 的拦截器中。为了避免由于拦截器未记录完整响应而导致重定向,应将此拦截器放置在认证拦截器和错误拦截器之间。
Dio()
..interceptors.addAll([
AuthInterceptor(),
SwaggerInterceptor(),
ErrorInterceptor(),
]);
1. 初始化插件
[必需]
SwaggerGenerator.instance.initial(
Swagger(
id: '1',
info: const SwaggerInfo(
title: 'Example API docs',
version: '1.0.0',
),
servers: const [
SwaggerServer(
url: 'https://example.swagger-test/api/v1',
description: 'Test',
),
],
components: SwaggerComponent(
securities: const [
SwaggerSecurity(
name: 'Authorization',
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
),
SwaggerSecurity(
name: 'Device-Type',
type: 'apiKey',
),
],
),
),
includeResponse: true,
);
2. 使用额外选项为路径添加详细信息
定义路径参数
默认情况下,库会从路径中提取查询参数。例如执行路径 /posts/1/comments
,则 swagger 路径将被创建为 "/posts/{postId}/comments"
。如果你希望自定义,可以在 dio 请求的选项中添加它。
final resp = await _dio.get(
'/posts/1/comments',
options: Options(
extra: {
'path': 'posts/{myPostId}/comments',
},
),
);
另一种方法是通过传递 pathParamsRegs
当调用 initial
时定义正则表达式规则来提取查询参数。
定义摘要或描述
同样可以使用额外选项来定义摘要或描述。
final resp = await _dio.get(
'/posts/1/comments',
options: Options(
extra: {
'summary': 'Summary of this API',
'description': 'This API executes an action',
},
),
);
3. 预览数据
库支持预览 JSON 数据。你可以复制 JSON 内容或将最新结构同步到 GitLab。可以通过以下方式导航:
SwaggerGenerator.instance.openPreviewPage(context);
4. 同步到 GitLab
输入你的 GitLab 信息后,可以同步最新结构到 GitLab。
示例
请参阅示例:/example
示例代码
import 'package:dio/dio.dart';
import 'package:example/auth_interceptor.dart';
import 'package:example/error_interceptor.dart';
import 'package:flutter/material.dart';
import 'package:swagger_generator/swagger_generator.dart';
const baseUrl = 'https://jsonplaceholder.typicode.com';
void main() {
WidgetsFlutterBinding.ensureInitialized();
SwaggerGenerator.instance.initial(
Swagger(
id: '1',
info: const SwaggerInfo(
title: 'Example API docs',
version: '1.0.0',
),
servers: const [
SwaggerServer(
url: baseUrl,
description: 'Json placeholder',
),
],
components: SwaggerComponent(
securities: const [
SwaggerSecurity(
name: 'Authorization',
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
),
],
),
),
includeResponse: true,
);
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Swagger Generator Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Swagger Generator Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late final Dio _dio;
[@override](/user/override)
void initState() {
_dio = Dio()
..options.baseUrl = baseUrl
..options.contentType = 'application/json'
..interceptors.addAll(
[
AuthInterceptor(),
SwaggerInterceptor(),
ErrorInterceptor(),
],
);
super.initState();
}
Future<void> _fetchPost() async {
final resp = await _dio.get('/posts/1/comments');
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('We have ${(resp.data as List).length} post'),
behavior: SnackBarBehavior.floating,
));
}
Future<void> _fetchCommentByPost() async {
final resp = await _dio.get(
'/comments?postId=1',
options: Options(
extra: {
'summary': 'Get comments in a post',
'description': 'Get comments in a post by passing a postId'
},
),
);
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('We have ${(resp.data as List).length} comments in post 1'),
behavior: SnackBarBehavior.floating,
));
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
_fetchPost();
},
child: const Text('Get all posts'),
),
ElevatedButton(
onPressed: () {
_fetchCommentByPost();
},
child: const Text('Get comments by postId'),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => SwaggerGenerator.instance.openPreviewPage(context),
child: const Icon(Icons.window),
),
);
}
}
更多关于Flutter API文档生成插件swagger_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter API文档生成插件swagger_generator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用swagger_generator
插件来生成API文档的代码案例。swagger_generator
是一个可以帮助你从Swagger/OpenAPI规范生成Dart代码的工具,这样你就可以在Flutter应用中轻松调用API。
首先,确保你的Flutter项目已经创建,并且你已经添加了swagger_generator
依赖。
- 添加依赖
在你的pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter:
sdk: flutter
# 其他依赖...
dev_dependencies:
swagger_generator: ^x.y.z # 请替换为最新版本号
build_runner: ^x.y.z # 确保build_runner也是最新版本
然后运行flutter pub get
来安装依赖。
- 准备Swagger/OpenAPI规范文件
确保你有一个有效的Swagger/OpenAPI规范文件,比如api.yaml
。这个文件定义了你的API端点和模型。
- 生成代码
在你的项目根目录下,运行以下命令来生成Dart代码:
flutter pub run build_runner build --delete-conflicting-outputs
你需要在你的build.yaml
文件中配置swagger_generator
,以便它知道如何处理你的Swagger文件。创建一个build.yaml
文件(如果还没有),并添加以下内容:
targets:
$default:
builders:
swagger_generator:swagger:
options:
input_file: "path/to/your/api.yaml" # 替换为你的Swagger文件路径
output_dir: "lib/generated" # 指定生成代码的输出目录
- 使用生成的代码
一旦代码生成完成,你可以在lib/generated
目录下找到生成的API客户端代码。这个代码通常包括服务类和模型类。
以下是一个简单的使用示例:
import 'package:flutter/material.dart';
import 'package:your_app_name/generated/api_client.dart'; // 导入生成的API客户端代码
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Swagger Generator Example'),
),
body: Center(
child: FutureBuilder<void>(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
// 假设fetchData返回了一个List<String>
return ListView.builder(
itemCount: snapshot.data?.length ?? 0,
itemBuilder: (context, index) {
return Text('${snapshot.data![index]}');
},
);
}
},
),
),
),
);
}
Future<List<String>> fetchData() async {
// 创建API客户端实例
final apiClient = ApiClient();
// 调用API(这里以获取一个列表为例)
try {
final response = await apiClient.yourEndpointGet(); // 替换为你的实际API方法
return response.data!.map((item) => item.toString()).toList(); // 根据实际情况调整
} catch (e) {
throw Exception('Failed to fetch data: $e');
}
}
}
注意:
ApiClient
是生成的API客户端类。yourEndpointGet
是生成的API方法,你需要根据你的Swagger文件定义替换为实际的方法名。- 生成的代码可能会包含错误处理和序列化的代码,所以请确保你了解生成的API结构。
这样,你就能够在Flutter应用中通过swagger_generator
插件生成的代码来调用API了。