Generating Dart models from JSON
In this article, we’ll explore how to generate Dart models from JSON using the json_serializable
package in Flutter. This package provides a set of annotations and code generation tools that help us map JSON objects to Dart classes automatically.
Setting up the environment
First, let’s add the json_serializable
package to our Flutter project. Open your project's pubspec.yaml
file and add the following dependencies:
dependencies:
json_annotation: ^4.4.0
json_serializable: ^4.4.0
dev_dependencies:
build_runner: ^2.1.4
The json_annotation
package provides the annotations we need to generate our models, while json_serializable
provides the tools to generate the code automatically. The build_runner
package is needed to run the code generation scripts.
After adding the dependencies, run flutter packages get
to download and install them.
Creating a model
Let’s say we have a JSON object like this:
{
"name": "Thepearldash",
"email": "thepearldash@example.com",
"age": 32
}
We want to create a Dart model to represent this object. To do so, we’ll create a new Dart file and define a class that matches the structure of the JSON object:
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable()
class User {
final String name;
final String email;
final int age;
User({
required this.name,
required this.email,
required this.age,
});
factory User.fromJson(Map<String, dynamic> json) =>
_$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
Here’s what’s happening in this code:
- We import the
json_annotation
package and include apart
directive that points to a generated file (user.g.dart
). - We define a
User
class with three properties:name
,email
, andage
. - We mark the class with the
@JsonSerializable
annotation. This annotation tells thejson_serializable
package to generate code for serializing and deserializing JSON objects to and from instances of this class. - We define a constructor that takes the three properties as required parameters.
- We define a
fromJson
factory method that takes aMap<String, dynamic>
object and returns aUser
instance. This method is generated by thejson_serializable
package. - We define a
toJson
method that returns aMap<String, dynamic>
object. This method is also generated by thejson_serializable
package.
Generating the code
Now that we have our model defined, we can generate the code that maps JSON objects to and from instances of our User
class.
To do so, we need to run the build_runner
package. Open a terminal window and run the following command:
flutter packages pub run build_runner build
This command tells build_runner
to generate code for all classes marked with the @JsonSerializable
annotation in our project.
After running this command, json_serializable
will generate a new file named user.g.dart
that contains the code for serializing and deserializing our User
class.
Using the model
Now that we have our User
model generated, we can use it in our Flutter app to map JSON objects to Dart instances and vice versa.
For example, let’s say we have a JSON API that returns a list of users. We can use the http
package to fetch the JSON data and convert it to a list of User
instances like this:
import 'dart:convert';
import 'package:http/http.dart' as http;
Future<List<User>> fetchUsers() async {
final response = await http.get(Uri.parse('https://example.com/users'));
if (response.statusCode == 200) {
final json = jsonDecode(response.body);
final List<dynamic> data = json['data'];
return data.map((userJson) => User.fromJson(userJson)).toList();
} else {
throw Exception('Failed to fetch users');
}
}
Here’s what’s happening in this code:
- We import the
http
package to make an HTTP request. - We define an asynchronous function
fetchUsers
that fetches the user data from the API and returns a list ofUser
instances. - We make an HTTP GET request to the API and check the response status code. If it’s
200
, we continue with the processing. - We decode the JSON response body using
jsonDecode
and extract thedata
field, which is assumed to be an array of user objects. - We map the list of user objects to a list of
User
instances using themap
method and theUser.fromJson
factory method generated byjson_serializable
.
We can then use this function to fetch the user data and display it in our Flutter app.
Conclusion
Generating Dart models from JSON can save us a lot of time and effort when working with JSON APIs in Flutter. The json_serializable
package provides us with the tools to generate this code automatically and keep it in sync with our JSON data structures.
In this article, we’ve seen how to create a User
model from a JSON object and generate the code for serializing and deserializing instances of this class. We've also seen how to use this model to fetch user data from a JSON API and map it to Dart instances in our Flutter app.
I hope this article helps you to work more efficiently with JSON data in your Flutter projects.