60 lines
1.5 KiB
Dart
60 lines
1.5 KiB
Dart
|
|
import 'package:dio/dio.dart';
|
||
|
|
import 'api_exception.dart';
|
||
|
|
import 'api_interceptor.dart';
|
||
|
|
import '../storage/token_storage.dart';
|
||
|
|
|
||
|
|
class ApiClient {
|
||
|
|
final Dio _dio;
|
||
|
|
final TokenStorage _tokenStorage;
|
||
|
|
final Future<bool> Function(String)? _refreshToken;
|
||
|
|
|
||
|
|
ApiClient({
|
||
|
|
required String baseUrl,
|
||
|
|
required TokenStorage tokenStorage,
|
||
|
|
Dio? dio,
|
||
|
|
Future<bool> Function(String)? refreshToken,
|
||
|
|
}) : _tokenStorage = tokenStorage,
|
||
|
|
_refreshToken = refreshToken,
|
||
|
|
_dio = dio ?? Dio(BaseOptions(baseUrl: baseUrl)) {
|
||
|
|
_dio.interceptors.add(
|
||
|
|
ApiInterceptor(
|
||
|
|
tokenStorage: _tokenStorage,
|
||
|
|
onTokenRefresh: _handleTokenRefresh,
|
||
|
|
),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
Dio get dio => _dio;
|
||
|
|
|
||
|
|
Future<bool> _handleTokenRefresh() async {
|
||
|
|
final refreshToken = await _tokenStorage.getRefreshToken();
|
||
|
|
if (refreshToken == null || _refreshToken == null) return false;
|
||
|
|
try {
|
||
|
|
final success = await _refreshToken!(refreshToken);
|
||
|
|
return success;
|
||
|
|
} catch (_) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<Response<T>> get<T>(String path, {Options? options}) async {
|
||
|
|
try {
|
||
|
|
return await _dio.get<T>(path, options: options);
|
||
|
|
} catch (e) {
|
||
|
|
throw ApiException.fromDioError(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<Response<T>> post<T>(
|
||
|
|
String path, {
|
||
|
|
dynamic data,
|
||
|
|
Options? options,
|
||
|
|
}) async {
|
||
|
|
try {
|
||
|
|
return await _dio.post<T>(path, data: data, options: options);
|
||
|
|
} catch (e) {
|
||
|
|
throw ApiException.fromDioError(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|