Paramclasses Academy - Blog

Tutorials Details

←
Post 25 of 40
→

How to Connect a Flutter App to a REST API and Fetch JSON Data

How to Connect a Flutter App to a REST API and Fetch JSON Data

November 2, 2026

❖ How to Connect a Flutter App to a REST API and Fetch JSON Data

❖ Welcome to Param Classes!

Welcome to another practical Flutter development tutorial at Param Classes!

In previous lessons, we learned how to create Flutter applications, work with widgets, manage application state, and store data locally using SQLite and Hive.

But many modern applications need information from an online server.

For example:

  • A shopping application needs to fetch product details.

  • A news application needs to display the latest news.

  • A school application needs to retrieve student information.

  • A weather application needs to show weather details.

  • A booking application needs to load available services.

To perform these tasks, Flutter applications communicate with servers using APIs.

In this tutorial, we will learn what REST APIs are, how JSON data works, how to connect Flutter with an API, and how to display the received information on the screen.

✦ 1. What Is an API?

API stands for Application Programming Interface.

An API allows two different software applications to communicate with each other.

For example, imagine you have developed a Flutter Student Management App. Student information is stored in a backend database.

Your Flutter application sends a request to the server. The server processes that request, retrieves the required student information, and sends a response back to Flutter.

The communication looks like this:

Flutter App → API Request → Backend Server → Database → API Response → Flutter App

The Flutter application does not need to connect directly to the server's database. It communicates through the API.

✦ 2. What Is a REST API?

REST stands for Representational State Transfer.

A REST API is a common way for applications to communicate with servers using HTTP requests.

REST APIs generally use different HTTP methods for different operations.

HTTP Method Purpose
GET Retrieve data
POST Send or create data
PUT Update existing data
PATCH Update selected fields
DELETE Delete data

For example, a Flutter application may use a GET request to retrieve a list of students from a PHP backend.

✦ 3. What Is JSON?

JSON stands for JavaScript Object Notation.

It is a lightweight data format commonly used to exchange information between frontend applications and backend servers.

Example JSON response:

{
  "id": 1,
  "name": "Rahul",
  "course": "Flutter",
  "mobile": "9876543210"
}

This response contains four fields:

  • id stores the student ID.

  • name stores the student's name.

  • course stores the course name.

  • mobile stores the mobile number.

Flutter can convert this JSON response into Dart objects and display the information using widgets.

✦ 4. Create a New Flutter Project

First, open Android Studio or VS Code.

Create a new Flutter project using the terminal:

flutter create api_demo

Move inside the project:

cd api_demo

Open the project in your preferred editor.

✦ 5. Install the HTTP Package

Flutter provides an HTTP package that helps applications communicate with web servers.

Open the terminal and run:

flutter pub add http

This package allows us to send HTTP requests such as GET and POST.

Official package documentation:

https://pub.dev/packages/http

✦ 6. Import the Required Packages

Open the lib/main.dart file.

Add these imports:

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

Understanding the imports:

  • dart:convert helps convert JSON text into Dart objects.

  • material.dart provides Flutter Material Design widgets.

  • http.dart allows us to send HTTP requests.

✦ 7. Fetch JSON Data Using a GET API

For this beginner example, we will use a sample public API that provides user information.

API URL:

https://jsonplaceholder.typicode.com/users

This API returns sample user records in JSON format.

Create a function to fetch the data:

Future<List<dynamic>> fetchUsers() async {

  final response = await http.get(
    Uri.parse('https://jsonplaceholder.typicode.com/users'),
  );

  if (response.statusCode == 200) {

    return jsonDecode(response.body);

  } else {

    throw Exception('Failed to load users');

  }
}

Explanation:

  1. http.get() sends a GET request to the API.

  2. Uri.parse() converts the URL into a URI.

  3. await waits for the server response.

  4. response.statusCode checks the HTTP status.

  5. response.body contains the returned JSON data.

  6. jsonDecode() converts JSON text into Dart data.

A status code of 200 generally indicates that the request was successful.

✦ 8. Display API Data Using ListView.builder

Now we will display the users received from the API.

Replace the code in main.dart with this complete beginner example:

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: UserScreen(),
    );
  }
}

class UserScreen extends StatefulWidget {
  const UserScreen({super.key});

  @override
  State<UserScreen> createState() => _UserScreenState();
}

class _UserScreenState extends State<UserScreen> {

  late Future<List<dynamic>> users;

  @override
  void initState() {
    super.initState();

    users = fetchUsers();
  }

  Future<List<dynamic>> fetchUsers() async {

    final response = await http.get(
      Uri.parse('https://jsonplaceholder.typicode.com/users'),
    );

    if (response.statusCode == 200) {

      return jsonDecode(response.body);

    } else {

      throw Exception('Failed to load users');

    }
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: const Text('API User List'),
        backgroundColor: Colors.blue,
        foregroundColor: Colors.white,
      ),

      body: FutureBuilder<List<dynamic>>(
        future: users,

        builder: (context, snapshot) {

          if (snapshot.connectionState == ConnectionState.waiting) {

            return const Center(
              child: CircularProgressIndicator(),
            );

          }

          if (snapshot.hasError) {

            return Center(
              child: Text('Error: ${snapshot.error}'),
            );

          }

          final userList = snapshot.data ?? [];

          return ListView.builder(

            itemCount: userList.length,

            itemBuilder: (context, index) {

              final user = userList[index];

              return Card(
                margin: const EdgeInsets.all(10),

                child: ListTile(

                  leading: CircleAvatar(
                    child: Text(user['id'].toString()),
                  ),

                  title: Text(user['name']),

                  subtitle: Text(user['email']),

                ),
              );

            },
          );

        },
      ),
    );
  }
}

✦ 9. Understand FutureBuilder in Flutter

When an application calls an API, it takes some time to receive the response.

Flutter provides FutureBuilder to manage the result of asynchronous operations.

In our example:

FutureBuilder<List<dynamic>>(
  future: users,
  builder: (context, snapshot) {
    // UI based on API response
  },
)

We use three important conditions:

1. Loading State

if (snapshot.connectionState == ConnectionState.waiting)

Displays a loading indicator while the API request is running.

2. Error State

if (snapshot.hasError)

Displays an error message when the request fails.

3. Success State

final userList = snapshot.data ?? [];

Displays the data received from the server.

These three states are important for creating a better user experience.

✦ 10. Understand JSON Parsing in Flutter

Sometimes, working directly with Map and List becomes difficult when an application contains many fields.

For better code organization, we can create a Dart model class.

Create a file named:

user_model.dart

Add this code:

class UserModel {

  final int id;
  final String name;
  final String email;

  UserModel({
    required this.id,
    required this.name,
    required this.email,
  });

  factory UserModel.fromJson(Map<String, dynamic> json) {

    return UserModel(
      id: json['id'],
      name: json['name'],
      email: json['email'],
    );

  }
}

Explanation:

  • UserModel defines the structure of user information.

  • id, name, and email are model properties.

  • fromJson() converts a JSON map into a Dart object.

For example:

final user = UserModel.fromJson({
  'id': 1,
  'name': 'Rahul',
  'email': 'rahul@example.com',
});

print(user.name);

This approach makes API code easier to understand and maintain.

✦ 11. How to Handle API Errors

Sometimes an API request may fail.

Possible reasons include:

  • Internet connection problems.

  • Incorrect API URL.

  • Server is unavailable.

  • Invalid authentication.

  • Request timeout.

  • Unexpected response format.

You can use try-catch to handle exceptions:

Future<void> loadData() async {

  try {

    final response = await http.get(
      Uri.parse('https://jsonplaceholder.typicode.com/users'),
    );

    if (response.statusCode == 200) {

      print(response.body);

    } else {

      print('Server Error: ${response.statusCode}');

    }

  } catch (e) {

    print('Something went wrong: $e');

  }
}

In real applications, display a helpful message to users instead of relying only on print().

✦ 12. Important Things to Remember When Using APIs

Before using an API in a real Flutter application, remember these points:

Internet permission: Android applications need internet permission. Check your Android manifest if network requests are not working.

For Android, open:

android/app/src/main/AndroidManifest.xml

Add this permission outside the application tag:

<uses-permission android:name="android.permission.INTERNET" />

Use HTTPS: Prefer secure HTTPS API endpoints.

Check status codes: Do not assume every API request will succeed.

Handle loading states: Show a progress indicator while waiting for data.

Parse JSON carefully: Check whether fields are missing or have unexpected data types.

Protect sensitive information: Do not hardcode secret API keys or private credentials in a public mobile application.

✦ 13. Common Mistakes Beginners Should Avoid

  1. Forgetting to install the HTTP package.

  2. Using an incorrect API URL.

  3. Forgetting to use await for asynchronous operations.

  4. Trying to display JSON text without parsing it.

  5. Ignoring API error responses.

  6. Calling the API repeatedly inside the widget's build() method.

  7. Not checking internet permission on Android.

  8. Assuming every JSON field will always contain a value.

Understanding these mistakes will help you troubleshoot API integration problems.

✦ 14. Practical Assignment for Beginners

Now it is your turn to practice!

Create a Flutter User Directory App using a REST API.

Your application should include:

  1. Fetch user data from a REST API.

  2. Display user names.

  3. Display email addresses.

  4. Display phone numbers.

  5. Show a loading indicator.

  6. Handle API errors.

  7. Add a refresh button to load data again.

  8. Create a separate Dart model class for user information.

Try to complete this project without copying the complete example.

❖ Conclusion

REST API integration is an important part of modern Flutter application development.

By connecting Flutter with APIs, developers can retrieve online data, communicate with backend servers, and build applications that use real-time information.

In this tutorial, we learned how to install the HTTP package, send GET requests, receive JSON responses, parse data, and display API information using FutureBuilder.

At Param Classes, our focus is on practical programming lessons that help beginners build real-world applications step by step.

Keep practicing API integration because it will be useful when you connect Flutter applications with PHP, MySQL, Firebase, and other backend technologies.

Keep Learning, Keep Building with Param Classes!

←
Post 25 of 40
→