Một ứng dụng mobile mà không có kết nối mạng thì chẳng khác nào một chiếc máy tính cầm tay 10 năm trước. Sức mạnh thực sự nằm ở việc lấy dữ liệu từ Server về điện thoại.
Trong Flutter, việc gọi API REST không khó, nhưng làm sao để chuyển đổi đống chữ JSON loằng ngoằng thành Object (Model) sịn sò để dùng trong Code thì lại là một nghệ thuật.
| Thư viện |
Ưu điểm |
Nhược điểm |
| http |
Resmi của Google, nhẹ, dễ dùng |
Ít tính năng nâng cao (Interceptor, Cancel) |
| dio |
Mạnh mẽ, nhiều đồ chơi (Interceptor, Download file) |
Cồng kềnh hơn một chút |
1. Vòng đời của một HTTP Request
Trước khi code, hãy hiểu luồng đi của dữ liệu:
- Request: App gửi một yêu cầu (GET/POST) kèm theo Header/Body lên địa chỉ Server.
- Processing: Server xử lý (truy vấn DB) và trả về kết quả.
- Response: Kết quả thường ở dạng chuỗi JSON.
- Parsing: App phải “dịch” chuỗi JSON đó thành class Dart để hiển thị.
2. JSON Parsing: Từ chuỗi vô tri thành Object có hồn
Đây là bước dễ sai nhất. Dart là ngôn ngữ định kiểu mạnh (Strongly Typed), nên bạn không thể cứ data['name'] bừa bãi như JavaScript được. Bạn cần tạo ra các Model Class.

Ví dụ JSON trả về:
{ "id": 1, "name": "Thanh", "email": "thanh@gmail.com" }
Chúng ta tạo class Dart tương ứng:
class User {
final int id;
final String name;
final String email;
User({required this.id, required this.name, required this.email});
// Hàm "thần thánh" để biến Map thành Object
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
name: json['name'],
email: json['email'],
);
}
}
3. Thực hành: Gọi API với thư viện http
Đầu tiên, thêm http vào pubspec.yaml. Sau đó viết hàm gọi API:
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<List<User>> fetchUsers() async {
final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
if (response.statusCode == 200) {
// 1. Decode JSON string -> List<dynamic>
List<dynamic> body = jsonDecode(response.body);
// 2. Map từng item -> User Object
List<User> users = body.map((item) => User.fromJson(item)).toList();
return users;
} else {
throw Exception('Failed to load users');
}
}
4. Xử lý lỗi (Error Handling) chuẩn chỉ
Đừng bao giờ tin tưởng mạng Internet. Nó có thể rớt bất cứ lúc nào. Vì vậy, luôn luôn phải bao bọc code gọi API trong khối try-catch.

Sử dụng FutureBuilder để hiển thị các trạng thái khác nhau lên UI:
– ConnectionState.waiting: Hiện vòng xoay Loading.
– snapshot.hasError: Hiện thông báo lỗi “Vui lòng kiểm tra mạng”.
– snapshot.hasData: Hiện danh sách User.
Kết nối API xong rồi, nhưng nếu người dùng tắt mạng thì sao? Ứng dụng trắng xóa à? Không được!
Bài tiếp theo: Lưu trữ local trong Flutter: SharedPreferences & SQLite để App chạy Offline.
👉 Cách lưu dữ liệu vào bộ nhớ máy để dùng khi mất mạng
💡 Bạn muốn học cách cấu hình Dio Interceptor để tự động Refresh Token (JWT)?
Kỹ thuật nâng cao này được dạy kỹ trong: Khóa học Lập trình Flutter Thực chiến