Overview #

Hampir setiap aplikasi mobile modern berkomunikasi dengan server — mengambil data, mengirim formulir, memproses pembayaran, atau menerima notifikasi. Di Flutter, semua komunikasi jaringan dibangun di atas protokol HTTP/HTTPS dan ekosistem package yang kaya. Sebelum membahas implementasi spesifik, penting memahami fondasi: bagaimana HTTP bekerja, apa saja komponen request dan response, dan bagaimana Flutter mengarsitektur layer networking yang bersih.

Bagaimana HTTP Bekerja #

HTTP (HyperText Transfer Protocol) adalah protokol komunikasi antara client (aplikasi Flutter) dan server (backend API). Setiap interaksi mengikuti pola yang sama: client mengirim request, server memproses, dan mengembalikan response.

Flutter App (Client)                    Server (API Backend)
      │                                       │
      │──── HTTP Request ──────────────────→  │
      │     Method: GET                       │  Proses request
      │     URL: /api/produk                  │  Query database
      │     Headers: Authorization: Bearer... │  Format response
      │     Body: (opsional)                  │
      │                                       │
      │  ←─── HTTP Response ─────────────── │
      │     Status: 200 OK                    │
      │     Headers: Content-Type: app/json   │
      │     Body: [{"id":1,"nama":"..."}]     │
      │                                       │

HTTP Methods #

Setiap request menggunakan method yang menunjukkan operasi yang ingin dilakukan:

GET     -- Ambil data (read-only, tidak ada body request)
         Contoh: GET /api/produk          → daftar produk
         Contoh: GET /api/produk/123      → produk dengan ID 123

POST    -- Buat data baru (body berisi data yang akan dibuat)
         Contoh: POST /api/produk         → tambah produk baru
         Contoh: POST /api/auth/login     → login

PUT     -- Update seluruh data (replace)
         Contoh: PUT /api/produk/123      → update semua field produk 123

PATCH   -- Update sebagian data
         Contoh: PATCH /api/produk/123    → update hanya field tertentu

DELETE  -- Hapus data
         Contoh: DELETE /api/produk/123  → hapus produk 123

Status Code #

Server merespons dengan status code tiga digit yang menunjukkan hasil request:

2xx -- SUKSES
  200 OK             -- Request berhasil (GET, PUT, PATCH)
  201 Created        -- Data berhasil dibuat (POST)
  204 No Content     -- Berhasil tapi tidak ada body (DELETE)

3xx -- REDIRECT
  301 Moved Permanently  -- URL telah berpindah permanen
  304 Not Modified       -- Data tidak berubah (dari cache)

4xx -- ERROR CLIENT (kesalahan dari sisi kita)
  400 Bad Request    -- Request tidak valid (format salah, data kurang)
  401 Unauthorized   -- Belum login / token tidak valid
  403 Forbidden      -- Login tapi tidak punya izin
  404 Not Found      -- Resource tidak ditemukan
  422 Unprocessable  -- Data gagal validasi di server

5xx -- ERROR SERVER (kesalahan di sisi server)
  500 Internal Server Error  -- Error tak terduga di server
  502 Bad Gateway            -- Server upstream bermasalah
  503 Service Unavailable    -- Server sedang down / overload

Headers #

Headers adalah metadata yang dikirim bersama request atau response:

// Headers request yang umum
{
  'Content-Type': 'application/json',       // format body yang kita kirim
  'Accept': 'application/json',             // format response yang kita minta
  'Authorization': 'Bearer eyJhbG...',      // token autentikasi
  'Accept-Language': 'id-ID',               // bahasa yang diinginkan
  'X-Request-ID': 'uuid-unik',             // ID untuk tracking/debugging
}

// Headers response yang umum
{
  'Content-Type': 'application/json',       // format body yang dikembalikan
  'Content-Length': '1234',                 // ukuran body dalam bytes
  'Cache-Control': 'max-age=3600',          // instruksi caching
  'X-RateLimit-Remaining': '95',            // sisa quota request
}

JSON — Format Data Universal #

JSON (JavaScript Object Notation) adalah format pertukaran data yang paling umum digunakan di REST API. Di Flutter, JSON dikonversi ke-dan-dari Dart objects:

// JSON dari server
{
  "id": 123,
  "nama": "Flutter Book",
  "harga": 150000.0,
  "tersedia": true,
  "kategori": ["buku", "programming"],
  "penerbit": {
    "nama": "Tech Publisher",
    "kota": "Jakarta"
  }
}

// Decode JSON dari String ke Map
import 'dart:convert';

final Map<String, dynamic> data = jsonDecode(responseBody);
final String nama = data['nama'];           // 'Flutter Book'
final double harga = data['harga'];         // 150000.0
final List kategoris = data['kategori'];    // ['buku', 'programming']
final String kotaPenerbit = data['penerbit']['kota'];  // 'Jakarta'

// Encode Map ke JSON String
final String jsonString = jsonEncode({
  'nama': 'Produk Baru',
  'harga': 99000,
});

Arsitektur Layer Networking #

Networking yang bersih memisahkan tanggung jawab ke beberapa layer. Ini memudahkan testing, pemeliharaan, dan pergantian implementasi:

┌─────────────────────────────────────────────┐
│                 UI Layer                     │
│  Widget → hanya tampilkan data, kirim aksi   │
└───────────────────┬─────────────────────────┘
                    │ data models (Produk, User, dll)
┌───────────────────▼─────────────────────────┐
│            State Management Layer            │
│  Notifier/Bloc → koordinasi loading & state  │
└───────────────────┬─────────────────────────┘
                    │ domain objects
┌───────────────────▼─────────────────────────┐
│              Repository Layer                │
│  Abstraksi sumber data → interface bersih    │
│  ProdukRepository.getAll() → List<Produk>    │
└───────────────────┬─────────────────────────┘
                    │ data transfer objects (DTO)
┌───────────────────▼─────────────────────────┐
│             Data Source Layer                │
│  RemoteDataSource → HTTP calls dengan Dio    │
│  LocalDataSource  → cache dengan Hive/SQLite │
└───────────────────┬─────────────────────────┘
                    │ HTTP requests/responses
┌───────────────────▼─────────────────────────┐
│              Network Layer                   │
│  Dio/HTTP client → interceptors, timeout     │
└─────────────────────────────────────────────┘

Keuntungan arsitektur berlapis ini sangat nyata saat pengembangan. Jika API backend berubah, kita hanya mengubah RemoteDataSource tanpa menyentuh UI atau logika bisnis. Jika ingin menambah cache offline, cukup tambah LocalDataSource di Repository.


Peta Ekosistem Package Networking Flutter #

HTTP CLIENT:
  http         -- package resmi Dart, sederhana dan ringan
                  cocok untuk kebutuhan dasar
  dio          -- powerful, interceptors, retry, cancel token
                  pilihan utama untuk produksi

SERIALISASI JSON:
  dart:convert -- built-in, manual parsing
  json_annotation + json_serializable -- code generation, aman
  freezed      -- immutable models + serialisasi + union types

GRAPHQL:
  graphql_flutter -- Query/Mutation/Subscription widgets
  ferry           -- alternatif dengan type-safety lebih baik

STORAGE LOKAL (untuk cache):
  shared_preferences -- key-value sederhana
  hive               -- NoSQL cepat, cocok untuk cache
  sqflite            -- SQL relasional

AUTH:
  flutter_secure_storage -- simpan token secara aman
  google_sign_in         -- OAuth Google
  sign_in_with_apple     -- OAuth Apple

KONEKSI:
  connectivity_plus -- deteksi status koneksi internet

REST vs GraphQL — Pilihan Arsitektur API #

REST (Representational State Transfer):
  ✓ Sederhana dan familiar
  ✓ Didukung oleh hampir semua backend framework
  ✓ Mudah di-cache oleh CDN
  ✓ Dokumentasi matang (OpenAPI/Swagger)
  ✗ Over-fetching: response sering berisi data yang tidak dibutuhkan
  ✗ Under-fetching: butuh beberapa request untuk satu tampilan
  ✗ Versioning API bisa kompleks

GraphQL:
  ✓ Client meminta data yang dibutuhkan saja (no over/under-fetching)
  ✓ Single endpoint untuk semua operasi
  ✓ Schema yang self-documenting
  ✓ Subscriptions real-time built-in
  ✗ Kompleksitas lebih tinggi di backend
  ✗ Caching lebih sulit
  ✗ Kurva belajar lebih curam

Pilih REST jika: tim familiar, backend sudah ada, kebutuhan standar
Pilih GraphQL jika: banyak tipe klien, data kompleks, butuh real-time

Ringkasan #

  • HTTP adalah protokol request-response antara Flutter (client) dan server. Setiap request punya method (GET/POST/PUT/DELETE), URL, headers, dan opsional body.
  • Status code menunjukkan hasil: 2xx sukses, 4xx error client, 5xx error server. Selalu handle status code, jangan hanya handle exception.
  • JSON adalah format pertukaran data universal — gunakan jsonDecode() dan jsonEncode() dari dart:convert untuk konversi dasar.
  • Gunakan arsitektur berlapis: UI → State Management → Repository → Data Source → HTTP Client. Setiap layer punya satu tanggung jawab.
  • Ekosistem Flutter punya banyak pilihan: http untuk kebutuhan sederhana, Dio untuk produksi (interceptors, retry, cancel), graphql_flutter untuk GraphQL.
  • REST cocok untuk sebagian besar kebutuhan. GraphQL cocok untuk aplikasi dengan banyak tipe klien dan kebutuhan data yang kompleks.

← Sebelumnya: State Management Best Practice   Berikutnya: Dio & HTTP →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact