There are 2 ways

  1. Manual Serialization for small applications
  2. Serialization JSON using Code Generation Library.

Approach -1 Manual Serialization for small applications


import ‘dart:convert’;
Map<String, dynamic> user = jsonDecode(jsonString); //jsonDecode method returns the Map<String, dynamic>
print('Howdy, ${user['name']}!');
print('We sent the verification link to ${user['email']}.');

Now if you want to do Manual Serialization and DeSerialization in class.

class User {
  final String name;
  final String email;


// Named Constructor - Take JSON and create 	
  User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        email = json['email'];

// Convert  user object into JSON
  Map<String, dynamic> toJson() => {
        'name': name,
        'email': email,

// Calling 
Map<String, dynamic> userMap = jsonDecode(jsonString);
var user = User.fromJson(userMap);

print('Howdy, ${}!');
print('We sent the verification link to ${}.');

2. Serialization Using Code Generation Library

Although there are other libraries available, this guide uses json_serializable, an automated source code generator that generates the JSON serialization boilerplate for you.
To include jsonserializable in your project, you need one regular dependency, and two dev dependencies. In short, dev dependencies are dependencies that are not included in our app source code—they are only used in the development environment.

  # Your other regular dependencies here
  json_annotation: <latest_version>

  # Your other dev_dependencies here
  build_runner: <latest_version>
  json_serializable: <latest_version>
import 'package:json_annotation/json_annotation.dart';

part 'data.g.dart';

class Data {
    required this.firstName,
    required this.lastName,
    required this.avatar,

The fromJson and toJson methods will be generated by the json_serializable package. Some of the class attributes are annotated with @JsonKey because the name defined in the Map (and returned by the API request) is different than their attribute name.

You can trigger the code generation using the following command:

flutter pub run build_runner build

Keep the code generator running in a server so that any new changes to the class automatically trigger the code generation. Use the following command to do this:

flutter pub run build_runner serve --delete-conflicting-outputs

The --delete-conflicting-outputs flag helps to regenerate a part of the generated class if any conflicts are found.

Using with DIO

We will define a method for retrieving a single user data from the API by passing an id:

// Get Handling
Future<User> getUser({required String id}) async {
    // Perform GET request to the endpoint "/users/<id>"
    Response userData = await _dio.get(_baseUrl + '/users/$id');

    // Prints the raw data returned by the server
    print('User Info: ${}');

    // Parsing the raw JSON data to the User class
    User user = User.fromJson(;

    return user;
// Post Handling
Post Handing
Future<UserInfo?> createUser({required UserInfo userInfo}) async {
  UserInfo? retrievedUser;

  try {
    Response response = await
      _baseUrl + '/users',
      data: userInfo.toJson(),

    print('User created: ${}');

    retrievedUser = UserInfo.fromJson(;
  } catch (e) {
    print('Error creating user: $e');

  return retrievedUser;
// Conversion Code
// Using 
Map<String, dynamic> userMap = jsonDecode(jsonString);
var user = User.fromJson(userMap);

That' all Folks See you in next Blog 😎