I am exploring the dio_cache_interceptor package in Flutter. This package provides logic for implementing caching and handling the HTTP Status Code 304.
While testing this package I tested a particular scenario. My configuration is-
Future createDioInstance() async {
final dio = Dio();
dio.options.validateStatus = (status) {
return status != null && (status >= 200 && status < 300 || status == 304);
};
final directory = await getApplicationDocumentsDirectory();
final cacheOptions = CacheOptions(
store: HiveCacheStore(directory.path),
policy: CachePolicy.request,
maxStale: Duration(seconds: 30,)
hitCacheOnErrorExcept: [500, 404]);
dio.interceptors.add(CustomDioCacheInterceptor(options: cacheOptions));
return dio;
}
class CustomDioCacheInterceptor extends DioCacheInterceptor {
CustomDioCacheInterceptor({
required super.options,
}) : _cacheOptions = options;
late final CacheOptions _cacheOptions;
}
The CustomDioCacheInterceptor
is a sub class of the DioCacheInterceptor
class. It just overrides the onRequest()
and onResponse()
method and just call the corresponding super()
methods. No custom logic.
Now, the logic for loading the cached response (in the package) is-
Future _loadCacheResponse(RequestOptions request) async {
final options = _getCacheOptions(request);
final cacheKey = options.keyBuilder(request);
final cacheStore = _getCacheStore(options);
final response = await cacheStore.get(cacheKey);
if (response != null) {
// Purge entry if staled
final maxStale = CacheOptions.fromExtra(request)?.maxStale;
if ((maxStale == null || maxStale == const Duration(microseconds: 0)) &&
response.isStaled()) {
await cacheStore.delete(cacheKey);
return null;
}
return response.readContent(options);
}
return null;
}
bool isStaled() {
return maxStale?.isBefore(DateTime.now()) ?? false;
}
Based on the maxStale
, the cached response is either deleted (if stale) or returned (if not stale).
This _loadCacheResponse()
is called in onRequest()
when the request comes in and in onResponse()
when the response has a status code of 304. This is the exact logic in the package.
Potential Issue-
maxStale
duration of 30 seconds. This would mean that the cached response has a maxStale of 30 seconds.This breaks on the upper layers (api-calling layer) because we got an empty response body. This happened because in onRequest(), the cached data was not stale but in onResponse() the data got stale.