You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何复用ApiResponse父模型适配不同数据结构的API响应

复用ApiResponse适配对象/数组类型的data字段

你的问题很典型——很多API会根据接口场景返回单个对象或数组,但我们完全可以通过泛型来复用ApiResponse父模型,不用写两个几乎一样的类。下面是具体的实现方案:

1. 将ApiResponse重构为泛型类

把原来固定的List<Data>替换为泛型T,让data字段可以适配任意类型(单个对象或列表)。同时修改fromJson方法,让它接受一个工厂函数来解析具体的data类型:

class ApiResponse<T> {
  bool success;
  String message;
  T data;

  ApiResponse({this.success, this.message, this.data});

  // 泛型工厂方法,接受一个将json转为T的函数
  factory ApiResponse.fromJson(
    Map<String, dynamic> json,
    T Function(dynamic jsonData) fromJsonT,
  ) {
    return ApiResponse(
      success: json['success'],
      message: json['message'],
      // 调用传入的函数解析data,不管是对象还是数组都能处理
      data: json['data'] != null ? fromJsonT(json['data']) : null,
    );
  }
}

2. 定义具体的数据模型(比如User)

不需要再用模糊的Data类,直接定义对应业务的User模型,兼容两种接口的字段:

class User {
  String code;
  String name; // 对应/all-users接口的name字段
  String firstName; // 对应/user-details接口的firstName字段
  String lastName;
  String email;

  User({
    this.code,
    this.name,
    this.firstName,
    this.lastName,
    this.email,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      code: json['code'],
      name: json['name'],
      firstName: json['firstName'],
      lastName: json['lastName'],
      email: json['email'],
    );
  }
}

3. 解析两种不同的API响应

现在可以用同一个ApiResponse类,分别解析数组和单个对象的响应:

解析/all-users(数组类型data)

// 假设你已经拿到了接口返回的jsonMap
Map<String, dynamic> allUsersJson = ...;

final apiResponse = ApiResponse<List<User>>.fromJson(
  allUsersJson,
  // 传入数组解析逻辑:把List里的每个item转成User
  (jsonData) => (jsonData as List)
      .map((item) => User.fromJson(item as Map<String, dynamic>))
      .toList()
      .cast<User>(),
);

// 使用数据:apiResponse.data就是List<User>类型
List<User> users = apiResponse.data;

解析/user-details/USR001(单个对象类型data)

Map<String, dynamic> userDetailsJson = ...;

final apiResponse = ApiResponse<User>.fromJson(
  userDetailsJson,
  // 传入单个对象解析逻辑:直接转成User
  (jsonData) => User.fromJson(jsonData as Map<String, dynamic>),
);

// 使用数据:apiResponse.data就是User类型
User user = apiResponse.data;

优化:封装数组解析的辅助方法

如果有很多列表类型的接口,可以封装一个辅助函数来简化代码:

// 辅助函数:把json数组转成指定类型的列表
T Function(dynamic) listParser<T>(T Function(Map<String, dynamic>) itemParser) {
  return (jsonData) => (jsonData as List)
      .map((item) => itemParser(item as Map<String, dynamic>))
      .toList()
      .cast<T>();
}

这样解析数组时就更简洁了:

final apiResponse = ApiResponse<List<User>>.fromJson(
  allUsersJson,
  listParser(User.fromJson),
);

这种方式的核心优势是完全复用ApiResponse类,同时保持了类型安全——编译器会帮你检查data字段的类型,避免运行时错误。

内容的提问来源于stack exchange,提问作者user8057270

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 09:22:40