Flutter REST API integration with Retrofit - Part-2

Last updated Aug 06, 2021

In this flutter retorfit integration we are going to call api request with retrofit API. Flutter framework contains Networking and JSON serialization modules.
For small JSON data, these modules will work and need to write a lot of code. We need to know REST API integration in Flutter with Http

If you know about Android/iOS, you may know about a few libraries like Retrofit, AlamoFire. These libraries will handle all data parsing and we need to write less code. This updated code contains updated all dependencies with null safety feature.

In this post, we are going to learn how to use the Retrofit library in Flutter.

Will do below implementations in this post

  • Calling network APIs.
  • Parsing JSON data.
  • Showing JSON data in a Listview.

 

Note: If you’re a newbie to Flutter, please check out the Flutter tutorial for an overview of the basics of working with this SDK.

 

In this example we have a button, when we tap on button it will fetch data from API and shows the list of users with the Listview widget

 

 

Retrofit Rest API

 

 

Retrofit Implementation

 

Let's get started

Step 1: Create a Flutter Application

Step 2:
To work with Retrofit implementation in Flutter we need to add below dependencies in pubspec.yaml file

 

dependencies:
  retrofit: ^2.0.0
  logger: ^1.0.0
  dio:
  json_annotation: ^4.0.1
  json_serializable: ^4.1.3
  retrofit_generator: ^2.0.0+3
    build_runner: ^2.0.5
    analyzer:

 

Dio is our Http client, handling the connection for us.
Retrofit is a Dio client that makes consuming REST APIs easier for us. Those coming from Android will be pleased to see it in Flutter I guess ????
Build runner is used for code generation in Dart, apart from the pub
JSON Serializable: Creates Model class from JSON data

 

Step 3:

In this post for User data, we are using the API "https://gorest.co.in/public-api/users"

Let's create an abstract class ApiRequest

 

@RestApi(baseUrl: "https://gorest.co.in/public-api/")
abstract class ApiRequest{
  factory ApiRequest(Dio dio,{required String baseUrl}) =_ApiRequest;

  @GET("/users")
  Future<ResponseData> getUsers();

}

 

This class is working as a repository which will handle all network call methods.

in the above code, it will show error on the _ApiRequest variable.

To remove this error we need to add part 'apirequest.g.dart'; in the import statement

and run flutter pub run build_runner build command.
 

This will generate apirequest.g.dart file and contains all data about creating Retrofit instance and fetching data from the network

 

Step 4: Create data classes

Our API will return a list of users 

{
      code: 200,
      meta: {
          pagination: {
              total: 1676,
              pages: 84,
              page: 1,
              limit: 20
            }
          },
      data: [
          {
              id: 1,
              name: "Mrs. Somnath Namboothiri",
              email: "somnath_namboothiri_mrs@baumbach-nitzsche.com",
              gender: "Female",
              status: "Active",
              created_at: "2020-08-31T03:50:04.198+05:30",
              updated_at: "2020-08-31T03:50:04.198+05:30"
          },
      ]
}

 

So let's create a data.dart file and add below code

import 'package:json_annotation/json_annotation.dart';
part 'data.g.dart';
@JsonSerializable()
class User{
  late  int id;
  late String name;
  late  String email;
  late String gender;
  late String status;
  late String created_at;
  late String updated_at;

  User({required this.id, required this.name, required this.email,required this.gender, required this.status, required this.created_at, required this.updated_at});

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

@JsonSerializable()
class ResponseData{
  late int code;
  late  dynamic meta;
  late  List<dynamic>data;
  ResponseData({required this.code, this.meta, required this.data});
  factory ResponseData.fromJson(Map<String, dynamic> json) => _$ResponseDataFromJson(json);
  Map<String, dynamic> toJson() => _$ResponseDataToJson(this);

}

 

The above code will do auto serialization of the JSON data.
at this time it will show errors

so let's add part 'data.g.dart'; and run below command 
flutter pub run build_runner build command

 

Step 5: 
Call API with retrofit object

FutureBuilder<ResponseData> _buildBody(BuildContext context) {
  final client = ApiRequest(Dio(BaseOptions(contentType: "application/json")),baseUrl: 'https://gorest.co.in/public-api/');
  return FutureBuilder<ResponseData>(
    future: client.getUsers(),
    builder: (context, snapshot) {
      print('snapshot.error ${snapshot.error}');
      if (snapshot.connectionState == ConnectionState.done) {

        final  posts = snapshot.data;
        print(posts);
        if(posts!=null)
          {
            return _buildPosts(context, posts);
          }else
            {
              return Center(
                child: Container(),
              );
            }

      } else {
        return Center(
          child: CircularProgressIndicator(),
        );
      }
    },
  );
}

 

 

Complete code

main. dart file

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_retrofit/data.dart';

import 'apirequest.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(

        primarySwatch: Colors.green,

        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {


  bool pressed = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text("Retrofit Implementation - Flutter"),
      ),
      body: pressed ? _buildBody(context):Center(
        child: RaisedButton(child: Text("Fetch Users",style: TextStyle(color: Colors.white,fontSize: 18),),color: Colors.green,
            onPressed: () => {setState(() {
              pressed = true;

            })}),
      ),
    );
  }
}

FutureBuilder<ResponseData> _buildBody(BuildContext context) {
  final client = ApiRequest(Dio(BaseOptions(contentType: "application/json")),baseUrl: 'https://gorest.co.in/public-api/');
  return FutureBuilder<ResponseData>(
    future: client.getUsers(),
    builder: (context, snapshot) {
      print('snapshot.error ${snapshot.error}');
      if (snapshot.connectionState == ConnectionState.done) {

        final  posts = snapshot.data;
        print(posts);
        if(posts!=null)
          {
            return _buildPosts(context, posts);
          }else
            {
              return Center(
                child: Container(),
              );
            }

      } else {
        return Center(
          child: CircularProgressIndicator(),
        );
      }
    },
  );
}

Widget _buildPosts(BuildContext context, ResponseData posts) {
  return
    ListView.builder(itemBuilder: (context,index){
      return Card(
        child: ListTile(

          leading: Icon(Icons.account_box,color: Colors.green,size: 50,),
          title: Text(posts.data[index]['name'],style: TextStyle(fontSize: 20),),
          subtitle: Text(posts.data[index]['email']),
        ),
      );
    },itemCount: posts.data.length,
   );

}

 

apirequest.dart

import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';

import 'data.dart';

part 'apirequest.g.dart';
@RestApi(baseUrl: "https://gorest.co.in/public-api/")
abstract class ApiRequest{
  factory ApiRequest(Dio dio,{required String baseUrl}) =_ApiRequest;

  @GET("/users")
  Future<ResponseData> getUsers();

}

 

data.dart file

import 'package:json_annotation/json_annotation.dart';
part 'data.g.dart';
@JsonSerializable()
class User{
  late  int id;
  late String name;
  late  String email;
  late String gender;
  late String status;
  late String created_at;
  late String updated_at;

  User({required this.id, required this.name, required this.email,required this.gender, required this.status, required this.created_at, required this.updated_at});

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

@JsonSerializable()
class ResponseData{
  late int code;
  late  dynamic meta;
  late  List<dynamic>data;
  ResponseData({required this.code, this.meta, required this.data});
  factory ResponseData.fromJson(Map<String, dynamic> json) => _$ResponseDataFromJson(json);
  Map<String, dynamic> toJson() => _$ResponseDataToJson(this);

}

 

 

Flutter Search - ListView Filter Search

 

Tags: Retrofit, Rest API, Network calls, JSON Serialization

 

Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

9684 Views