Integrating Flutter REST Api With Example

In this article, I am going to explain how you can call flutter rest api in your mobile app. Flutter provides http library for our api calls. http is future based library. You can also check out sample at HERE.

This http package includes high-level functions and classes that make it easy to use HTTP resourcesfor flutter rest api. For Api Call, I uses this fake rest api for demo.

 

Add below line under dependencies section in pubspec file

http: ^0.12.0+4

 

Create Json Response Parser classes

I generate three classes User, Address and Company for parsing my api data. You have to create response parser classes according to your api data. This classes includes factory constructor that parse data from json.

 
import 'address.dart';
import 'company.dart';

class User {
  int id;
  String name, email, phone, website;
  Address address;
  Company company;

  User(
      {this.id,
      this.name,
      this.email,
      this.phone,
      this.website,
      this.address,
      this.company});

  factory User.fromJSON(Map<String, dynamic> parsedJson) {
    return User(
      id: parsedJson['id'],
      name: parsedJson['name'],
      email: parsedJson['email'],
      phone: parsedJson['phone'],
      website: parsedJson['website'],
      address: Address.fromJSON(parsedJson['address']),
      company: Company.fromJSON(parsedJson['company']),
    );
  }
}
 
class Address {
  String street, suite, city, zipcode;

  Address({this.street, this.suite, this.city, this.zipcode});

  factory Address.fromJSON(Map<String, dynamic> parsedJson) {
    return Address(
      street: parsedJson['street'],
      suite: parsedJson['suite'],
      city: parsedJson['city'],
      zipcode: parsedJson['zipcode'],
    );
  }
}
 
class Company {
  String name, catchPhrase, bs;

  Company({this.name, this.catchPhrase, this.bs});

  factory Company.fromJSON(Map<String, dynamic> parsedJson) {
    return Company(
        name: parsedJson['name'],
        catchPhrase: parsedJson['catchPhrase'],
        bs: parsedJson['bs']);
  }
}
 

Create async method for api call

http package provides different methods like get,post etc. You need to select method according to your api. You must set api url as parameter in api method function.
 
First we need to convert response body into Json. Then we need to check response status using status code. If status code is 200 then response is success and we can parse json data otherwise we need to throw exception and display error to users.
 
import 'package:http/http.dart' as http;
Future<List<User>> fetchUsers() async {
    final response =
        await http.get('https://jsonplaceholder.typicode.com/users');
    if (response.statusCode == 200) {
      var getUsersData = json.decode(response.body) as List;
      var listUsers = getUsersData.map((i) => User.fromJSON(i)).toList();
      return listUsers;
    } else {
      throw Exception('Failed to load users');
    }
  }
 

Call created async method

We created async method as above. Now we need to call this async method in initstate() method. Stateful widget provides initstate() method. initstate method is called first when related stateful widget is executed.  

Future<List<User>> listUsers;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    listUsers = fetchUsers();
  }
 

Display data

We need to use FutureBuilder widget for display api data in our app. FutureBuilder is specifically used in flutter for asynchronous data. In the future parameter we have to pass already parsed json data. builder parameter is used to check state of future: loading, success, error.
 
We also show indicator for api loading using CircularProgressIndicator widget. When api call is finished then we hide indicator widget and display api data.
 
@override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
        body: FutureBuilder<List<User>>(
      future: listUsers,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
             
        } else if (snapshot.hasError) {
          return Center(
            child: Text("${snapshot.error}"),
          );
        }
        return Center(
          child: CircularProgressIndicator(
            backgroundColor: Colors.cyanAccent,
          ),
        );
      },
    ));
  }
 
 

Final Code

 
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import 'models/user.dart';

class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return HomeState();
  }
}

class HomeState extends State<Home> {
  Future<List<User>> listUsers;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    listUsers = fetchUsers();
  }

  Future<List<User>> fetchUsers() async {
    final response =
        await http.get('https://jsonplaceholder.typicode.com/users');
    if (response.statusCode == 200) {
      var getUsersData = json.decode(response.body) as List;
      var listUsers = getUsersData.map((i) => User.fromJSON(i)).toList();
      return listUsers;
    } else {
      throw Exception('Failed to load users');
    }
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
        body: FutureBuilder<List<User>>(
      future: listUsers,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return ListView.separated(
              itemBuilder: (context, index) {
                var user = (snapshot.data as List<User>)[index];
                return Container(
                  padding: EdgeInsets.all(10),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Text(
                        user.name,
                        style: TextStyle(
                            fontWeight: FontWeight.bold, fontSize: 22),
                      ),
                      SizedBox(height: 5),
                      Text(user.email),
                      SizedBox(height: 5),
                      Text(user.address.street +
                          " " +
                          user.address.suite +
                          " " +
                          user.address.city +
                          " " +
                          user.address.zipcode),
                      SizedBox(height: 5),
                      Text(user.phone),
                      SizedBox(height: 5),
                      Text(user.website),
                      SizedBox(height: 5),
                      Text(user.company.name),
                      SizedBox(height: 5),
                      Text(user.company.catchPhrase),
                    ],
                  ),
                );
              },
              separatorBuilder: (context, index) {
                return Divider();
              },
              itemCount: (snapshot.data as List<User>).length);
        } else if (snapshot.hasError) {
          return Center(
            child: Text("${snapshot.error}"),
          );
        }
        return Center(
          child: CircularProgressIndicator(
            backgroundColor: Colors.cyanAccent,
          ),
        );
      },
    ));
  }
}

import 'package:flutter/material.dart';
import 'package:flutterrestapicallsample/home.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Home(),
    );
  }
}

flutter rest api

 

Leave a Reply