If you are keen to know what exactly it goes to build a simple app which displays the result from API call, you have landed at the right place.

This article will guide you on various topics such as

  • How to handle sensitive data like API keys.
  • Make API calls.
  • Best way to JSON serialization.
  • Handle Large JSON data that is sufficient to create the jank user experience.

Let’s first see what actually the complete app looks like.

Design inspiration from here So Let’s get started.

1) How to handle sensitive data like API keys

Suppose you are working on an open source project and you don’t want to let the world know the API keys you have used for making API call, This strategy might help you.

Here you have secrets.json file contains all the keys.

{
  "marvel_public_key": "XYZ_API_KEY",
  "marvel_private_key":"XYZ_API_KEY"
}

Don’ forget to add this file to .gitignore Now create another file named assecretloader.dart which has functions that load the JSON file and create a secret object out of it.

Future<Secret> load() {
  return rootBundle.loadStructuredData<Secret>(this.secretPath,
          (jsonStr) async {
        final secret = Secret.fromJson(json.decode(jsonStr));
        return secret;
      });
}

you can create more functions to retrieve any specific key depending upon your use case.

Finally, here the code that will retrieve the secret object and is ready to be used by our API.

SecretLoader(secretPath: 'assets/json/secrets.json')
    .load()
    .then((Secret s) {
      print("${s.marvelPrivateApiKey} and ${s.marvelPublicApiKey}");
}

This article describes all the details about it.

2) Make API calls.

Future<HerosHub> herosHub;
url = "https://gateway.marvel.com:443/v1/public/characters?limit=5&apikey=${s.marvelPublicApiKey}&ts=$ts&hash=$hash";
Future<HerosHub> _fetchData(String url) async {
  var res = await http.get(url);
  var decodedJson = jsonDecode(res.body);
  return HerosHub.fromJson(decodedJson);
}
//Make api call
herosHub = _fetchData(url);

Just this much code is required to make API call and here we have desired herosHub object that used to represent API response after JSON serialization and that brings us to next point.

3)JSON serialization

There are two main ways to perform JSON serialization.

  • Manual serialization
  • Automated serialization using code generation

Manual serializations take more time to write code by hand and may produce some errors and most probably typo errors so, in this project, Automated serialization is used to simplify our life. so let’s see how actually it is done.

The first step is to add the required libraries to pubspec.yaml.

dependencies:
  # Your other regular dependencies here
  json_annotation: ^2.0.0

dev_dependencies:
  # Your other dev_dependencies here
  build_runner: ^1.0.0
  json_serializable: ^2.0.0

and model class is updated to generate automatic JSON parsing code such as

heroshub.dart 
import 'package:json_annotation/json_annotation.dart';
part 'heroshub.g.dart';

@JsonSerializable()
class HerosHub {

  HerosHub(this.code, this.status,this.data);

  int code;
  String status;
  Data data;

  factory HerosHub.fromJson(Map<String, dynamic> json) => _$HerosHubFromJson(json);

  Map<String, dynamic> toJson() => _$HerosHubToJson(this);
}

Hit this command in terminal

flutter packages pub run build_runner watch

On successful completion of the above command, heroshub.g.dart file will be created and contain necessary code for JSON parsing.

4) Handle Large JSON data that is sufficient to create the jank user experience.

You might be knowing that Flutter runs on Dart but you should also know that Dart is Single Threaded. Sometimes you may need to perform heavy lifting such as parsing large JSON or downloading photos then, In that case, you should assign this job to isolates.

Basically, Any work that takes more than 16ms, Use Isolates.

In our case parsing JSON is definitely going to get more than 16ms since we have a lot of characters data to parse. We can modify the code to adopt isolates as such.

Future<HerosHub> _fetchData(String url) async {
  var response = await http.get(url);

  // Now Use the compute function if parsing takes more than 16ms using seperate isolates
  return compute(parseHeros, response.body);
}

// A function that will convert a response body into a HeroHub
HerosHub parseHeros(String responseBody) {
  var decodedJson = jsonDecode(responseBody);
  return HerosHub.fromJson(decodedJson);
}

compute function will take input as data to parse and function that is actually going to parse data.

That’s it.

I hope you have understood the basics of building the simple Flutter app.

Clone it. Play with it

 

Thanks for reading this article. If you like it, click on 👏 to rate it out of 50and also share with your friends. It means a lot to me.

For more about programming, follow me and Aubergine Solutions, so you’ll get notified when we write new posts.

Check out my other article on Options to Animate in Flutter.