http_client_cache 1.0.0
http_client_cache: ^1.0.0 copied to clipboard
A Dart package for HTTP request caching and network optimization. Provides flexible caching mechanisms to improve performance and reduce network load in Dart and Flutter applications.
http_client_cache #
The http_client_cache
package provides
a simple and efficient way to cache HTTP responses in Dart and Flutter applications. It allows you to store and retrieve cached responses, reducing the need for redundant network requests and improving the performance of your application.
Installation #
For Dart #
Run the following command:
dart pub add http_client_cache
For Flutter #
Run the following command:
flutter pub add http_client_cache
Usage #
To use the http_client_cache
package, you need to create an instance of HttpClientProxy
and use it with your HTTP client. Here's a basic example:
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:http_client_cache/http_client_cache.dart';
import 'package:http_client_interceptor/http_client_interceptor.dart';
Future<void> main() async {
final cache = HttpCache();
// create a cache instance which persists the cache entries on disk
// final dir = Directory('cache');
// await cache.initLocal(dir);
// create a cache instance which persists the cache entries in memory
await cache.initInMemory();
unawaited(
http.runWithClient(
_myDartApp,
() => HttpClientProxy(
interceptors: [
cache,
],
),
),
);
}
Future<void> _myDartApp() async {
final client = http.Client();
final response = await client.get(Uri.parse('https://api.example.com/data'));
print(response.body);
}
For Flutter #
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http_client_cache/http_client_cache.dart';
import 'package:http_client_interceptor/http_client_interceptor.dart';
import 'package:path_provider/path_provider.dart';
void main() {
// the HttpCache interceptor
late final HttpCache httpCache;
unawaited(
// Create a new [HttpClientProxy] with the [HttpCache] interceptor
// and make it the default [http.Client] for the [http.Client.new] factory method.
//
// A better way may be to create the [http.Client] and inject it where it is needed,
// instead of running your application with [runWithClient].
//
// For better performance, reuse the same [http.Client] for multiple http requests. So that
// open connections are reused.
http.runWithClient(
() async {
// needed for getApplicationCacheDirectory
WidgetsFlutterBinding.ensureInitialized();
// we need to init the cache in the runWithClient callback
// because the runWithClient callback creates a new Zone
// and we need to init the cache in the same zone.
httpCache = HttpCache();
final cacheDirectory = await getApplicationCacheDirectory();
await httpCache.initLocal(cacheDirectory);
runApp(const MyApp());
},
() => HttpClientProxy(
interceptors: [
httpCache,
],
),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
// add your code here
}
}
Advanced Usage #
You can also use a HttpInterceptorWrapper
to customize the cache-control
header for specific requests.
import 'dart:async';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:http_client_cache/http_client_cache.dart';
import 'package:http_client_interceptor/http_client_interceptor.dart';
Future<void> main() async {
final cache = HttpCache();
// create a cache instance which persists the cache entries on disk
// final dir = Directory('cache');
// await cache.initLocal(dir);
// create a cache instance which persists the cache entries in memory
await cache.initInMemory();
unawaited(
http.runWithClient(
_myDartApp,
() => HttpClientProxy(
interceptors: [
_CacheControlInterceptor(),
cache,
],
),
),
);
}
Future<void> _myDartApp() async {
final client = http.Client();
final response = await client.get(Uri.parse('https://api.example.com/data'));
print(response.body);
}
class _CacheControlInterceptor extends HttpInterceptorWrapper {
@override
Future<OnResponse> onResponse(http.StreamedResponse response) async {
final cacheControlHeader = response.headers[HttpHeaders.cacheControlHeader];
if (cacheControlHeader == null) {
return OnResponse.next(response);
}
// Add/override the cache control max-age parameter to cache the response.
// In production, there should be some logic to having different caching
// strategies for different content/mime types and/or urls.
final cacheControl = CacheControl.dynamicContent(
maxAge: const Duration(seconds: 60),
staleWhileRevalidate: const Duration(seconds: 30),
staleIfError: const Duration(seconds: 300),
);
// Create new headers map with the updated cache control
final newHeaders = Map<String, String>.from(response.headers);
newHeaders[HttpHeaders.cacheControlHeader] = cacheControl.toString();
return OnResponse.next(response.copyWith(headers: newHeaders));
}
}
Compatibility #
See http_client_interceptor
for how to use this package with popular Dart http packages,
like Chopper, Dio, Retrofit, http_image_provider
and other http
comppatible packages.