Flutter API Integration Explained: HTTP Requests, FutureBuilder & Error Handling Guide

Learn Flutter API integration step by step. Understand HTTP requests, JSON parsing, FutureBuilder, loading states, error handling, and real-world best practices.

Introduction

Modern mobile applications rely heavily on APIs. Whether it is login authentication, product listing, user profiles, or dashboard data — everything usually comes from a backend server.

In Flutter, API integration is simple but requires understanding asynchronous programming, HTTP requests, and proper error handling.

In this complete guide, we will cover:

  • How HTTP works in Flutter
  • Making GET and POST requests
  • Parsing JSON data
  • Using FutureBuilder
  • Handling loading and error states
  • Best practices for production apps

Adding HTTP Package

To make API calls, we need the http package. Add it inside pubspec.yaml.

dependencies:
  http: ^0.13.6

Then run flutter pub get.

Making a GET Request

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

Future> fetchPosts() async {
  final response = await http.get(
    Uri.parse("https://jsonplaceholder.typicode.com/posts"),
  );

  if (response.statusCode == 200) {
    return jsonDecode(response.body);
  } else {
    throw Exception("Failed to load posts");
  }
}

This function:

  • Sends a GET request
  • Checks status code
  • Parses JSON
  • Returns data

Using FutureBuilder

FutureBuilder is used to build UI based on asynchronous data.

FutureBuilder(
  future: fetchPosts(),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator();
    }

    if (snapshot.hasError) {
      return Text("Error: ${snapshot.error}");
    }

    final posts = snapshot.data as List;

    return ListView.builder(
      itemCount: posts.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(posts[index]['title']),
        );
      },
    );
  },
)

Understanding ConnectionState

  • waiting: API is loading
  • done: Data received
  • active: Stream active
  • none: No connection

Making a POST Request

Future loginUser(String email, String password) async {
  final response = await http.post(
    Uri.parse("https://example.com/login"),
    body: {
      "email": email,
      "password": password,
    },
  );

  if (response.statusCode == 200) {
    print("Login success");
  } else {
    throw Exception("Login failed");
  }
}

Creating a Model Class

Instead of using dynamic JSON, create model classes.

class Post {
  final int id;
  final String title;

  Post({required this.id, required this.title});

  factory Post.fromJson(Map json) {
    return Post(
      id: json['id'],
      title: json['title'],
    );
  }
}

Parsing JSON to Model

Future> fetchPosts() async {
  final response = await http.get(
    Uri.parse("https://jsonplaceholder.typicode.com/posts"),
  );

  if (response.statusCode == 200) {
    List data = jsonDecode(response.body);
    return data.map((e) => Post.fromJson(e)).toList();
  } else {
    throw Exception("Error fetching posts");
  }
}

Handling Loading State Properly

Always show a loading indicator while fetching data. Never leave the screen blank.

Handling Errors Gracefully

Instead of crashing the app:

  • Show user-friendly messages
  • Provide retry option
  • Log errors for debugging

Common Beginner Mistakes

  • Calling API inside build()
  • Not handling exceptions
  • Ignoring status codes
  • Using dynamic everywhere instead of models

Best Practices

  • Keep API logic inside separate service files
  • Use model classes
  • Handle network errors properly
  • Use proper state management for large apps

Real-World Architecture Tip

In production apps:

  • Create API service class
  • Separate repository layer
  • Use state management (Provider, Bloc, etc.)
  • Avoid calling API directly inside UI widgets

Conclusion

API integration is a core skill for Flutter developers. Once you understand HTTP requests, JSON parsing, FutureBuilder, and proper error handling, you can build real-world applications.

Master this concept, and you are ready to connect your Flutter apps to real backend systems.

Share

What's Your Reaction?

Like Like 0
Dislike Dislike 0
Love Love 0
Funny Funny 0
Angry Angry 0
Sad Sad 0
Wow Wow 0