Caching basically is the process of storing the response from a request on-device storage to avoid frequent network requests to the API or any other resource on the internet.
You might already use CachedNetworkImage
in Flutter to avoid multiple network requests for loading images in your flutter app. This helps users by saving the mobile data and also reduces the requests made to your server for the same resource which was loaded before.
We can do this for API calls in our app too. If you followed any other articles on the internet, they usually show you the MemCacheStore as the caching store. But the problem with this is that the MemCache will be cleared when you quit the app. If you want to cache the response and preserve it on the app reopen then this is the guide for you.
In this we’ll use Hive as our cache store, Hive is a lightweight and blazing-fast key-value database written in pure Dart. We can use hive as our cache by using the network request URI as the key and the response provided by the request as the value.
Add the required packages to the pubspec.yaml
file in your project.
hive: ^2.0.5
dio: ^4.0.6
dio_cache_interceptor: ^3.3.0
dio_cache_interceptor_hive_store: ^3.2.0
The first line imports the hive library and the other three are the Dio and Dio interceptor packages that we’ll use to intercept the requests made using Dio and capture the data to cache.
Cache Dir
The folder where you want to store the data that is being cached by the API calls. To follow the best practices we’ll use the flutter provided method to get the temporary folder of the device.
var cacheDir = await getTemporaryDirectory();
This above line will get the temporary directory object which we can use to direct the hive to store the cache in this folder.
If you want to, you can also make a custom path to the folder to which your app has access, but I don’t recommend that as it might eat up users’ storage and they can’t clear cache from the app settings unless you provide a way to.
build Cache-Store
Now we’ll make a cacheStore object which we need to pass to the caching interceptor to indicate the cache references.
var cacheStore = HiveCacheStore(cacheDir.path,hiveBoxName: "your_app_name",);
The above HiveCacheStore
takes two arguments, cacheDirPath(string) and the hiveBoxName(string) which can be anything you want.
CacheOptions
We have the cache-store object we created in the above step, we use that to make a cacheOptions object for the interceptor which tells it how to manage the cache.
var customCacheOptions = CacheOptions(
store: cacheStore,
policy: CachePolicy.forceCache,
priority: CachePriority.high,
maxStale: const Duration(minutes: 5),
hitCacheOnErrorExcept: [401, 404],
keyBuilder: (request) {
return request.uri.toString();
},
allowPostMethod: false,
);
For the cacheOptions object, we pass the cacheStore, policy, priority, staleDuration, keyBuilder, and others. Let me explain
CachePolicy.forceCache
— you’ll save every successful GET request.
CachePolicy.refreshForceCache
— when the origin server has no cache config, Requests regardless of cache availability, and Caches if a response has cache directives.
CachePolicy.refresh
— Requests regardless of cache availability, Cache if the response has cache directives.
CachePolicy.noCache
— Requests and skips cache save even if the response has cache directives.
This just tells how much priority must be given to the cache over network data.
high
, low
and normal
Here you set the duration of how long should your cache should stay live.
The returned string of this method is used as the key for the cache in the cacheStore, make sure it’s unique for each request otherwise your cache might corrupt the data received on a different API call.
This argument just tells the interceptor if it should also cache the post-method responses which aren’t usually cached.
Building Dio
Finally, we build Dio object and pass in the configured cache options and the caching interceptor for caching the request made through this Dio object.
var customDio = Dio()..interceptors.add(DioCacheInterceptor(options: customCacheOptions));
And that’s it.
Now all your get requests made on the Dio object we created above will be cached to the user’s device storage temp dir.
Now, your API won't call the server every second and eat up your cloud resources.
Also Published Here