Sign in
Struggling to fetch dynamic data in your Flutter app without bloating it with hardcoded content? REST APIs allow apps to connect with external servers and exchange real-time data—but how do you make it work in Flutter? This blog breaks down how to connect, fetch, and manage data from REST APIs using Flutter. By reading this, you’ll learn how to structure API calls, manage responses, handle errors gracefully, and keep your code clean. Perfect for developers aiming to build responsive, data-driven mobile apps. If you're ready to get practical with real API calls in Flutter, this guide simplifies each step with code examples and visual diagrams.
A REST API (Representational State Transfer) is a set of rules that allows programs to communicate with each other using HTTP methods like GET
, POST
, PUT
, and DELETE
.
Common HTTP Methods in REST APIs:
Method | Purpose | Example Use Case |
---|---|---|
GET | Read data | Fetch list of users |
POST | Create new data | Submit a new form |
PUT | Update existing data | Edit user profile |
DELETE | Remove existing data | Delete a user account |
Mobile applications often rely on backend data—think weather apps, social media feeds, or shopping carts. Flutter, by itself, doesn’t provide backend data management. So we need APIs to retrieve and modify data stored on remote servers.
Before writing any code:
Create a Flutter project
Run:
1flutter create api_demo 2cd api_demo 3
Add HTTP package
Edit pubspec.yaml
:
1dependencies: 2 flutter: 3 sdk: flutter 4 http: ^0.13.5 5
Then run:
1flutter pub get 2
1import 'package:http/http.dart' as http; 2import 'dart:convert'; 3
1final String apiUrl = "https://jsonplaceholder.typicode.com/posts"; 2
1Future<List<dynamic>> fetchPosts() async { 2 final response = await http.get(Uri.parse(apiUrl)); 3 4 if (response.statusCode == 200) { 5 return jsonDecode(response.body); 6 } else { 7 throw Exception('Failed to load posts'); 8 } 9} 10
1class PostsPage extends StatelessWidget { 2 3 Widget build(BuildContext context) { 4 return Scaffold( 5 appBar: AppBar(title: Text("Posts")), 6 body: FutureBuilder( 7 future: fetchPosts(), 8 builder: (context, snapshot) { 9 if (snapshot.connectionState == ConnectionState.waiting) { 10 return Center(child: CircularProgressIndicator()); 11 } 12 13 if (snapshot.hasError) { 14 return Center(child: Text("Error: ${snapshot.error}")); 15 } 16 17 final List posts = snapshot.data as List; 18 19 return ListView.builder( 20 itemCount: posts.length, 21 itemBuilder: (context, index) { 22 return ListTile( 23 title: Text(posts[index]['title']), 24 subtitle: Text(posts[index]['body']), 25 ); 26 }, 27 ); 28 }, 29 ), 30 ); 31 } 32} 33
Never assume the API will always work perfectly. You need to prepare for timeouts, 404s, or malformed data.
1try { 2 final response = await http.get(Uri.parse(apiUrl)); 3 4 if (response.statusCode == 200) { 5 return jsonDecode(response.body); 6 } else { 7 throw Exception("Server returned: ${response.statusCode}"); 8 } 9} catch (e) { 10 throw Exception("Network error: $e"); 11} 12
Use models to represent data
Avoid working with raw maps. Create Dart classes for each data type.
1class Post { 2 final int id; 3 final String title; 4 final String body; 5 6 Post({required this.id, required this.title, required this.body}); 7 8 factory Post.fromJson(Map<String, dynamic> json) { 9 return Post( 10 id: json['id'], 11 title: json['title'], 12 body: json['body'], 13 ); 14 } 15} 16
Refactor API logic into services
1class ApiService { 2 final String apiUrl = "https://jsonplaceholder.typicode.com/posts"; 3 4 Future<List<Post>> fetchPosts() async { 5 final response = await http.get(Uri.parse(apiUrl)); 6 7 if (response.statusCode == 200) { 8 List data = jsonDecode(response.body); 9 return data.map((item) => Post.fromJson(item)).toList(); 10 } else { 11 throw Exception('Failed to load posts'); 12 } 13 } 14} 15
REST API communication is a key part of making your Flutter app dynamic and connected. With the http
package and clean architecture practices, you can manage server interactions with confidence. This guide helped you learn how to fetch, parse, and display data, while also handling errors and organizing code for readability. Start small, build modularly, and you'll find it much easier to maintain and scale your applications.