如何复用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
相关产品推荐
相关产品推荐

