How to use json_serializable package for complex response models - Flutter

Viewed 36

I have seen several examples on how to use json_serializable package to auto-generate response models. But almost all of these examples have simple response structure. For example, have a look at the Json response for a student's data.

{
  "name": "Something",
  "age": 12,
  "id": 2773
}

It's fairly easy to serialize this Json response. One of the ways is below

@JsonSerializable()
class Student {
  String name;
  int age;
  int roll_number;
 
  Student(
    this.name,
    this.age,
    this.roll_number,
  ) {}

  factory Student.fromJson(Map<String, dynamic> input) => _$StudentFromJson(input);

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

I am considering this example as simple because the response does not contain any non-primitive data in it. Let's take a look at this response now

{
  "name": "Something",
  "age": 12,
  "id": 2773,
  "marks": {
    "physics": 30,
    "maths": 20,
    "english": 30,
  }
}

We can have the files layed out like this

In the file student.dart

@JsonSerializable()
class Student {
  String name;
  int age;
  int roll_number;
  Marks marks;
 
  Student(
    this.name,
    this.age,
    this.roll_number,
    this.marks
  ) {}

  factory Student.fromJson(Map<String, dynamic> input) => _$StudentFromJson(input);

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

And in the file marks.dart

@JsonSerializable()
class Marks {
  int physics;
  int maths;
  int english;
 
  Marks(
    this.physics,
    this.maths,
    this.english,
  ) {}

  factory Marks.fromJson(Map<String, dynamic> input) => _$MarksFromJson(input);

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

I have two questions for the latter response scenario.

  1. If the response contains non-primitive data, is it necessary to serialize those data in a separate file, as I did with the Marks class. Or is there a way by which I can keep the class Marks in the file student.dart and serialize the whole response. If I can, how?
  2. My actual question was related to a project that i'm working on, in which I have multiple API calls in different sections of the project. The API response follows a same skeletal structure i.e.
Response {
 primitive data variables,
 Data data,
}

I'm receiving the actual response data in the Data class. Suppose I follow the serializing pattern that I mentioned in the example above, i.e. serialize Response class in one file and serialize Data class in another. Then i’ll have multiple Data class files all over the project. Won’t that create confusion to the other developers as to which data.g.dart file belongs to which response.g.dart file. The class Response’s name would be different depending on what type of response it fetches, for instance, DogResponse or UserResponse. But the key that stores the actual data in each of these response classes will have the same name i.e. Data, at least it has the same name in current scenario. Is there a way where I could keep the Data class of each response class in the response class itself? If now, how shall I tackle this problem of serialization.

0 Answers
Related