json_fetcher 2.0.4 copy "json_fetcher: ^2.0.4" to clipboard
json_fetcher: ^2.0.4 copied to clipboard

Convenient fetching of JSON data with caching, auth, logging. Wrapper over standard Dart http package.

pub package codecov

Motivation #

Imagine a user launching the app for the second time and seeing a skeletal loading screen or progress bar, especially in parts of the UI where the data doesn't change often. This is not a good UX.

To fix this, we can load the data from the cache in the first step, and then update the data in the second step.

We don't aim to minimize requests to the server, but to minimize the time it takes to display the data to the user.

Using #

import 'package:http/http.dart' as http;
import 'package:json_fetcher/json_fetcher.dart';
import 'package:path_provider/path_provider.dart';

Future<String> get cachePath => getApplicationCacheDirectory().then((dir) => dir.path);
final client = JsonHttpClient(http.Client(), createCache(cachePath));
final postsStream = JsonFetcher<Model>>(
  client,
  (json) => Model.fromJson(json),
).fetch('https://example.com/get-json');

Configuration #

At the first step you should create JsonHttpClient:

final jsonClient = JsonHttpClient(httpClient, cache);

HttpClient #

This package uses standard Dart http package.

Basicaly, is enough to use Client() for creating raw client:

final jsonClient = JsonHttpClient(Client(), cache);

So, you can configure client more precisely before creating JsonHttpClient itself.

Client httpClient() {
  if (Platform.isAndroid) {
    final engine = CronetEngine.build(
        cacheMode: CacheMode.memory,
        cacheMaxSize: 1000000);
    return CronetClient.fromCronetEngine(engine);
  }
  if (Platform.isIOS || Platform.isMacOS) {
    final config = URLSessionConfiguration.ephemeralSessionConfiguration()
      ..cache = URLCache.withCapacity(memoryCapacity: 1000000);
    return CupertinoClient.fromSessionConfiguration(config);
  }
  return IOClient();
}

final jsonClient = JsonHttpClient(httpClient(), cache);

Tip

The package contains convenitent client-wrapper with logging capabitility LoggableHttpClient, see Flutter example as use case.

Cache #

For creating cache just use convenient function createCache(path).

Note

path can be String of Future<String>

Future<String> variant is very useful for creating a client somewhere in DI at app startup, to prevent unneded waiting.

In Flutter Android/iOS app you can create client that caches data in standard cache directory with following snippet:

import 'package:path_provider/path_provider.dart';

Future<String> get path => getApplicationCacheDirectory().then((value) => value.path);

final jsonClient = JsonHttpClient(httpClient(), createCache(path));

Tip

Package exposes interface HttpCache, that can be implemented to use your own cache.

How it works #

If the data has changed (new data has arrived from the network), it will be updated in the second step. That's why we use Stream<T> instead of Future<T>. The stream's subscriber will get two snapshots.

If the data hasn't changed, the stream's subscriber will get one snapshot

If there is no cached copy, the stream's subscriber will get one snapshot.

Cache #

The cache data is managed by implementations of HttpCache.

dart:io (mobile/desktop)

HttpFilesCache stores data in files. Performance improved by using concurrent IO with synchronization by keys.

Web

HttpWebCache stores data in IndexedDB. It uses package:web from Dart team.

4
likes
150
points
59
downloads

Publisher

verified publisherjustprodev.com

Weekly Downloads

Convenient fetching of JSON data with caching, auth, logging. Wrapper over standard Dart http package.

Repository (GitHub)
View/report issues

Topics

#http #json #cache

Documentation

API reference

License

MIT (license)

Dependencies

http, logging, meta, web

More

Packages that depend on json_fetcher