Flutter JSON RPC代码生成插件json_rpc_codegen_builder的使用

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

Flutter JSON RPC代码生成插件json_rpc_codegen_builder的使用

json_rpc_codegen

CI/CD for json_rpc_codegen CI/CD for json_rpc_codegen_builder json_rpc_codegen pub版本 json_rpc_codegen_builder pub版本

这是一个dart代码生成器,用于为json_rpc_2包生成类型化的客户端和服务端代码。

功能

  • json_rpc_2包(dart的官方JSON-RPC 2.0实现)生成代码
  • 创建客户端和服务端类以及混合类
    • 可以直接使用客户端/服务端类来处理简单的用例
    • 如果需要处理对等方,或者希望有一个单一的服务端/客户端实例提供/消费多个定义,则可以通过使用基类和混合类来创建它们
  • 支持所有基本的dart类型和自定义JSON可序列化类型
    • 可以处理原始类型(如布尔值、整数等)
    • 可以处理无限嵌套的容器(如列表、集合、映射等)
    • 可以处理无限嵌套的记录
    • 可以处理高级的dart类型(如DateTime、Uri)
    • 可以通过fromJsontoJson方法处理自定义类型
  • 方法可以定义带类型的命名或位置参数
    • 支持所有类型
    • 带有服务器端JSON验证
    • 支持默认值(客户端或服务器端)

安装

由于这是一个构建器包,因此还需要安装注解和build_runner

dependencies:
  json_rpc_codegen: <最新版本>

dev_dependencies:
  build_runner: <最新版本>
  json_rpc_codegen_builder: <最新版本>

使用

API的使用非常简单。你需要创建一个抽象的dart类来描述接口,代码生成器会为你完成其余的工作:

import 'package:json_rpc_codegen/json_rpc_codegen.dart';

part 'my_class.g.dart';

enum Stage { all, pre, post }

[@jsonRpc](/user/jsonRpc)
abstract class _MyClass {
  void startServerTask({
    required int id,
    required String taskName,
    bool verbose = false,
    double? scale,
  });

  [@clientDefaults](/user/clientDefaults)
  double getProgress(int id, [Stage stage = Stage.all]);
}

这将为客户端和服务器实现生成大量的代码。请查看文档以了解如何控制哪些类被生成。默认情况下,将生成以下内容:

  • MyClassClientMixin: 继承自ClientBase类的混入类,包含接口的所有客户端实现
  • MyClassServerMixin: 继承自ServerBase类的混入类,包含接口的所有服务端实现
  • MyClassClient: 包含MyClassClientMixin的类,可以直接使用
  • MyClassServer: 包含MyClassServerMixin的类,可以直接使用

在大多数情况下,你可能想要直接使用MyClassClientMyClassServer。然而,如果你需要将多个接口组合成一个,或者你在处理Peer时,你可能想要使用混入类。

以下是生成的类的一个简化示例:

class MyClassClient {
  void startServerTask({
    required int id,
    required String taskName,
    // 所有可选参数都是可空的,因为默认值由服务器管理
    bool? verbose,
    double? scale,
  });

  // 非void方法成为Future,以便等待结果
  Future<double> getProgress(
    int id, [
    // 客户端默认值在客户端设置
    Stage stage = Stage.all,
  ]);
}

// 服务端是抽象的,因为你需要实现服务端方法的逻辑
abstract class MyClassServer {
  // 所有服务端方法使用FutureOr,可以同步或异步执行
  @protected
  FutureOr<void> startServerTask(
    int id,
    String taskName,
    // 服务端默认值由实现设置
    bool verbose,
    double? scale,
  );

  @protected
  FutureOr<double> getProgress(
    int id,
    // 客户端默认值在服务端侧是必需的
    Stage stage,
  );
}

要使用客户端,只需创建一个新的实例,就像使用标准的json_rpc_2客户端一样。对于服务端,创建自己的服务端类,该类扩展生成的服务端以实现服务端方法。然后你可以像使用json_rpc_2一样使用这个类,但不必关心任何注册。

文档

文档可在这里获取。一个完整的示例可以在这里找到。

示例代码

// ignore_for_file: unreachable_from_main

import 'package:json_rpc_codegen/json_rpc_codegen.dart';

part 'json_rpc_codegen_builder_example.g.dart';

enum Permission {
  read,
  write,
  administrate,
}

enum Stage { all, pre, post }

class User {
  final String firstName;
  final String lastName;

  const User(this.firstName, this.lastName);

  factory User.fromJson(Map<String, dynamic> json) =>
      throw UnimplementedError(json.toString());
}

[@jsonRpc](/user/jsonRpc)
// ignore: unused_element
abstract class _SampleApi {
  void hello(
    String name, [
    int times = 5,
    double? interval,
    int delay = 100,
  ]);

  [@clientDefaults](/user/clientDefaults)
  void notify({
    required int id,
    List<double> measures = const [1, 2],
  });

  String echo(String message);

  User? createUser(Map<String, Set<Permission>?> permissions);

  List<List<User>?> userMatrix([Permission? permission]);

  Map<String, List<Permission>> permissions();

  // ignore: prefer_void_to_null
  Null setHomepage({required Uri url, DateTime? timestamp});

  Uri findForDates(Iterable<DateTime> times);

  [@clientDefaults](/user/clientDefaults)
  void log(
    String message,
    dynamic context, [
    User user = const User('admin', 'admin'),
  ]);

  bool validate({
    User user = const User('admin', 'admin'),
    required User? authorizeFor,
    Permission permission = Permission.administrate,
    List<Uri>? resources,
  });

  Map merge(Set keys, Iterable values);

  (int, List<User>?, Permission, (int, int)) flip(
    ({int am, List<User>? ul, Permission pm, (int, int) pt}) record,
    () control,
  );

  void startServerTask({
    required int id,
    required String taskName,
    bool verbose = false,
    double? scale,
  });

  [@clientDefaults](/user/clientDefaults)
  double getProgress(int id, [Stage stage = Stage.all]);
}

void main() {}

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

1 回复

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


当然,下面是一个关于如何使用Flutter JSON RPC代码生成插件json_rpc_codegen_builder的示例。这个插件可以帮助你自动生成处理JSON RPC请求的代码,从而简化开发流程。

1. 添加依赖

首先,你需要在你的pubspec.yaml文件中添加json_rpc_codegen_builder的依赖。

dependencies:
  flutter:
    sdk: flutter
  json_rpc_2: ^2.0.0  # 确保你使用了兼容的json_rpc库

dev_dependencies:
  build_runner: ^2.0.0
  json_rpc_codegen_builder: ^1.0.0  # 假设最新版本为1.0.0

2. 创建JSON RPC Schema文件

接下来,你需要创建一个JSON RPC Schema文件,这个文件定义了你的RPC接口。例如,创建一个名为rpc_schema.json的文件:

{
  "jsonrpc": "2.0",
  "methods": [
    {
      "name": "sum",
      "params": [
        {
          "name": "a",
          "type": "integer"
        },
        {
          "name": "b",
          "type": "integer"
        }
      ],
      "result": {
        "type": "integer"
      }
    },
    {
      "name": "subtract",
      "params": [
        {
          "name": "a",
          "type": "integer"
        },
        {
          "name": "b",
          "type": "integer"
        }
      ],
      "result": {
        "type": "integer"
      }
    }
  ]
}

3. 生成代码

在你的项目根目录下,运行以下命令来生成代码:

flutter pub run build_runner build --build-filter=json_rpc_codegen_builder

这将在你的项目中生成对应的Dart文件,通常位于generated文件夹内。

4. 使用生成的代码

假设生成的代码文件名为rpc_api.dart,你可以在Flutter项目中使用它。以下是一个简单的示例:

import 'package:flutter/material.dart';
import 'generated/rpc_api.dart';  // 根据实际情况调整路径

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: RpcDemo(),
    );
  }
}

class RpcDemo extends StatefulWidget {
  @override
  _RpcDemoState createState() => _RpcDemoState();
}

class _RpcDemoState extends State<RpcDemo> {
  RpcClient _rpcClient = RpcClient('http://your-rpc-server-url');

  Future<void> callSum() async {
    try {
      var result = await _rpcClient.sum(10, 5);
      print('Sum result: $result');
    } catch (e) {
      print('Error: $e');
    }
  }

  Future<void> callSubtract() async {
    try {
      var result = await _rpcClient.subtract(10, 5);
      print('Subtract result: $result');
    } catch (e) {
      print('Error: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('JSON RPC Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: callSum,
              child: Text('Call Sum'),
            ),
            ElevatedButton(
              onPressed: callSubtract,
              child: Text('Call Subtract'),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项

  1. URL替换:确保在RpcClient初始化时,使用你的实际RPC服务器URL。
  2. 错误处理:在实际应用中,应添加更多的错误处理逻辑。
  3. 依赖版本:确保你使用的json_rpc_2json_rpc_codegen_builder版本兼容。

通过上述步骤,你应该能够使用json_rpc_codegen_builder插件来生成并使用JSON RPC接口的代码。

回到顶部