良好且可扩展的方法来创建网络客户端并在flutter中进行网络调用



我正在处理一个需要大量网络调用的大型项目。现在我已经创建了一个WebApiClass,并在这里编写了我的整个应用程序网络调用。但我认为这不是正确的方式。

样本代码

class WebApiCall{
Dio _dio = Dio();
Dio get dio {
_dio.options.baseUrl = BASE_URL;
_dio.options.headers = {'token': '$tokenKey'};
return _dio;
}
//I have written more than 100 networks calls like this in this class
Future<List<CompletedSessionData>?> getSessionData(int id) async{
List<CompletedSessionData>? completedSessionsData;
try{
final response = await dio.post('path', data: {'id': id});
if(response.statusCode == 200){
//Codes for decoding
}
} catch (e){
print(e);
}
return completedSessionsData;
}
}

我用这个类的提供者创建了一个依赖注入,以便在我的应用程序中到处使用它

我想重构我的代码,而不是把所有的网络调用都写在一个类中,我想把它分为多个类,但我不想创建多个Dio客户端,并多次提供我的基本URL和toke。

请给我一些好的、可扩展的方法来解决我的问题。

感谢

我不久前写过这篇文章,它基本上是一种服务,用于使用泛型类型所需的所有类型的调用:

class APIService {
APIService(this.baseUrl, this.token) {
_dio = Dio(BaseOptions(baseUrl: baseUrl));
_dio.options.headers["Authorization"] = "Bearer $token";
}
final String token;
final String baseUrl;
var _dio;
Future<T> get<T>(
{required String path,
T Function(Map<String, dynamic> json)? builder,
Map<String, dynamic>? query}) async {
try {
final response = await _dio.get(path, queryParameters: query);
return builder != null ? builder(response.data) : response.data;
} on DioError catch (e) {
debugPrint(e.message);
if (e.type == DioErrorType.other) {
throw SocketException(e.message);
} else if (e.type == DioErrorType.connectTimeout ||
e.type == DioErrorType.receiveTimeout ||
e.type == DioErrorType.sendTimeout) {
throw TimeoutException(e.message);
} else if (e.type == DioErrorType.response) {
throw HttpException(e.response != null ? e.response!.data.toString() : e.message);
} else {
rethrow;
}
}
}
Future<T> getValue<T>(
{required String path,
T Function(dynamic data)? builder,
Map<String, dynamic>? query}) async {
try {
final response = await _dio.get(path, queryParameters: query);
return builder != null ? builder(response.data) : response.data;
} on DioError catch (e) {
debugPrint(e.message);
if (e.type == DioErrorType.other) {
throw SocketException(e.message);
} else if (e.type == DioErrorType.connectTimeout ||
e.type == DioErrorType.receiveTimeout ||
e.type == DioErrorType.sendTimeout) {
throw TimeoutException(e.message);
} else if (e.type == DioErrorType.response) {
throw HttpException(e.response != null ? e.response!.data.toString() : e.message);
} else {
rethrow;
}
}
}
Future<List<T>> getAll<T>(
{required String path,
required List<T> Function(List<dynamic> json) builder,
Map<String, dynamic>? query}) async {
try {
final response = await _dio.get(path, queryParameters: query);
return builder(response.data);
} on DioError catch (e) {
debugPrint(e.message);
if (e.type == DioErrorType.other) {
throw SocketException(e.message);
} else if (e.type == DioErrorType.connectTimeout ||
e.type == DioErrorType.receiveTimeout ||
e.type == DioErrorType.sendTimeout) {
throw TimeoutException(e.message);
} else if (e.type == DioErrorType.response) {
throw HttpException(e.response != null ? e.response!.data.toString() : e.message);
} else {
rethrow;
}
}
}
Future<T> post<T, I>(
{required String path,
I? data,
T Function(Map<String, dynamic> json)? builder}) async {
try {
final response = await _dio.post(path, data: data);
return builder != null ? builder(response.data) : response.data;
} on DioError catch (e) {
debugPrint(e.message);
if (e.type == DioErrorType.other) {
throw SocketException(e.message);
} else if (e.type == DioErrorType.connectTimeout ||
e.type == DioErrorType.receiveTimeout ||
e.type == DioErrorType.sendTimeout) {
throw TimeoutException(e.message);
} else if (e.type == DioErrorType.response) {
throw HttpException(e.response != null ? e.response!.data.toString() : e.message);
} else {
rethrow;
}
}
}
Future<T> patch<T, I>(
{required String path,
I? data,
T Function(Map<String, dynamic> json)? builder}) async {
try {
final response = await _dio.patch(path, data: data);
return builder != null ? builder(response.data) : response.data;
} on DioError catch (e) {
debugPrint(e.message);
if (e.type == DioErrorType.other) {
throw SocketException(e.message);
} else if (e.type == DioErrorType.connectTimeout ||
e.type == DioErrorType.receiveTimeout ||
e.type == DioErrorType.sendTimeout) {
throw TimeoutException(e.message);
} else if (e.type == DioErrorType.response) {
throw HttpException(e.response != null ? e.response!.data.toString() : e.message);
} else {
rethrow;
}
}
}
Future<T> delete<T, I>(
{required String path,
I? data,
T Function(Map<String, dynamic> json)? builder}) async {
try {
final response = await _dio.delete(path, data: data);
return builder != null ? builder(response.data) : response.data;
} on DioError catch (e) {
debugPrint(e.message);
if (e.type == DioErrorType.other) {
throw SocketException(e.message);
} else if (e.type == DioErrorType.connectTimeout ||
e.type == DioErrorType.receiveTimeout ||
e.type == DioErrorType.sendTimeout) {
throw TimeoutException(e.message);
} else if (e.type == DioErrorType.response) {
throw HttpException(e.response != null ? e.response!.data.toString() : e.message);
} else {
rethrow;
}
}
}
}

然后我会在我的回购实现中这样使用它:

@override
Future<List<Ticket>>? getTickets({int? offset, int? state, String? query}) {
return _service.getAll(
path: APIPath.tickets(offset: offset, state: state, query: query),
builder: Ticket.ticketsFromJson);
}
@override
Future<Ticket>? getTicket(String id) {
return _service.get(
path: APIPath.ticket(id), builder: (data) => Ticket.fromJson(data));
}

最新更新