HTTP GET dengan package http
Ambil data dari REST API dan tampilkan di ListView.
Kenapa Perlu HTTP GET?
Bayangkan aplikasi warkopmu menampilkan daftar menu. Kalau menu di-hardcode di kode, setiap ganti harga kamu harus rilis update baru ke Play Store. Dengan HTTP GET, aplikasi mengambil data terbaru dari server setiap dibuka: menu, harga, stok, promo. Itulah kenapa hampir semua aplikasi produksi melakukan GET ke REST API.
Package http (dibuat oleh Dart team sendiri) adalah cara paling ringan dan standar untuk ini. Tidak ada setup rumit, tidak ada code generation, cuma satu dependency.
Setup
flutter pub add httpLalu import di file yang butuh:
import 'package:http/http.dart' as http;
import 'dart:convert';Contoh 1: GET Sederhana
Future<List<Produk>> ambilProduk() async {
final res = await http.get(
Uri.parse('https://api.contoh.com/produk'),
);
if (res.statusCode == 200) {
final jsonList = jsonDecode(res.body) as List;
return jsonList
.map((e) => Produk.fromJson(e as Map<String, dynamic>))
.toList();
} else {
throw Exception('Gagal memuat: ${res.statusCode}');
}
}Selalu cek statusCode sebelum parsing. Server bisa mengembalikan 404 atau 500 dengan body HTML, dan jsonDecode akan crash kalau kamu tidak cek dulu.
Contoh 2: GET dengan Query Params, Header, dan Timeout
Contoh yang lebih realistis, lengkap dengan pencarian, pagination, dan proteksi timeout:
Future<List<Produk>> cariProduk(String kataKunci, {int halaman = 1}) async {
final uri = Uri.https('api.contoh.com', '/produk', {
'q': kataKunci,
'halaman': '$halaman',
'limit': '20',
});
final res = await http
.get(uri, headers: {'Accept': 'application/json'})
.timeout(const Duration(seconds: 10));
switch (res.statusCode) {
case 200:
final jsonList = jsonDecode(res.body) as List;
return jsonList
.map((e) => Produk.fromJson(e as Map<String, dynamic>))
.toList();
case 401:
throw Exception('Sesi berakhir, silakan login ulang');
case 404:
throw Exception('Endpoint tidak ditemukan');
default:
throw Exception('Gagal memuat data (${res.statusCode})');
}
}Pakai Uri.https dengan map query parameter supaya spasi dan karakter spesial di-encode otomatis. Jangan rangkai URL pakai string interpolation mentah kalau parameternya datang dari input pengguna.
Menampilkan Hasil dengan FutureBuilder
FutureBuilder<List<Produk>>(
future: _futureProduk,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
final produk = snapshot.data ?? [];
return ListView.builder(
itemCount: produk.length,
itemBuilder: (context, i) => ListTile(title: Text(produk[i].nama)),
);
},
)Simpan future di initState (misal _futureProduk = cariProduk('kopi')). Jangan panggil fungsi GET langsung di dalam future: karena build bisa jalan berkali-kali dan request-mu ikut terkirim berkali-kali.
Edge Case yang Wajib Kamu Tahu
- Tanpa timeout, request bisa menggantung selamanya. Di jaringan jelek,
http.gettidak punya batas waktu bawaan. Selalu pasang.timeout(). - Localhost di emulator Android bukan
localhost. Pakaihttp://10.0.2.2:8000untuk menjangkau server di komputermu. Di iOS simulator,localhostbiasa tetap bisa. - Android 9+ memblokir HTTP polos. Kalau API lokalmu masih
http://, tambahkanandroid:usesCleartextTraffic="true"di manifest saat development, atau lebih baik pakai HTTPS sekalian. - Parsing bisa gagal walau status 200. Struktur JSON server bisa berubah sewaktu-waktu. Bungkus
fromJsondengan nilai default yang aman (as String? ?? '') seperti di modul model JSON.
Catatan teknis: Untuk API yang butuh login, tambahkan header
Authorization: Bearer $tokenseperti di modul HTTP POST. Simpan base URL di satu file konstanta supaya gampang diganti antara development dan production.
Kapan JANGAN Pakai Pendekatan Ini
- Jangan kirim data sensitif lewat query params. Password atau token di URL bisa tersimpan di log server dan history. Untuk mengirim data, pakai POST dengan body.
- Jangan panggil GET di dalam
build(). Setiap rebuild memicu request baru. Simpan future-nya atau pakai state management. - Kalau butuh fitur lanjutan (auto refresh token, retry otomatis, interceptor logging), package
httpterlalu polos. Saat itu tiba, pindah kedioyang memang dirancang untuk itu.
Tantangan
GET ke JSONPlaceholder
Ambil data dari https://jsonplaceholder.typicode.com/posts, parse menjadi List, dan tampilkan 10 judul pertama dalam ListView via FutureBuilder.