Lewati ke konten utama
Semua artikel
PemulaFondasi

Cara Kerja HTTP & Internet

Pahami request/response, HTTP methods, status codes, headers, dan JSON sebelum membangun API pertamamu.

21 menit baca

"Sebelum kamu bisa membangun rumah, kamu harus tahu dulu bagaimana bata, semen, dan pondasi bekerja."


Tentang E-Book Ini

Hampir semua tutorial backend dimulai langsung dari kode — "install Express, buat endpoint, return JSON." Tapi ada satu langkah yang sering dilewati: memahami mengapa semua itu bekerja.

Apa sebenarnya yang terjadi ketika browser mengirim request? Apa bedanya GET dengan POST? Kenapa ada status code 404 dan 500? Apa itu header? Kenapa response harus JSON? Apa itu REST?

E-book ini menjawab semua pertanyaan itu. Bukan dengan teori yang berat, tapi dengan analogi yang mudah dipahami dan contoh yang bisa langsung kamu coba sendiri. Setelah selesai, kamu akan punya mental model yang kuat — fondasi yang membuat semua e-book berikutnya terasa jauh lebih masuk akal.

Prasyarat: Tidak ada. E-book ini dirancang untuk siapa saja yang ingin belajar backend dari nol.


Daftar Isi

  1. Bagaimana Internet Bekerja
  2. HTTP: Bahasa Komputer di Internet
  3. HTTP Methods: Kata Kerja di API
  4. Status Codes yang Harus Kamu Hafal
  5. Headers: Metadata di Setiap Request
  6. JSON: Format Data di Web Modern
  7. REST: Konvensi Membangun API
  8. Coba Sendiri: curl & Hoppscotch

Bab 1: Bagaimana Internet Bekerja

Analogi Warung Makan

Bayangkan kamu pergi ke warung makan. Kamu datang, duduk, lalu pesan ke pelayan: "Satu nasi goreng." Pelayan mencatat, menyampaikan ke dapur, dapur masak, lalu makanan diantarkan ke mejamu.

Inilah persis yang terjadi ketika browser kamu membuka sebuah website:

  • Kamu = browser (Chrome, Firefox, Safari)
  • Pelayan = HTTP protocol
  • Dapur = server (komputer yang menyimpan website)
  • Pesanan = HTTP request
  • Makanan yang diantar = HTTP response

Dari Ketik URL sampai Halaman Muncul

Ketika kamu mengetik https://backendlabs.id dan menekan Enter, ini yang terjadi secara berurutan:

Langkah 1 — DNS Lookup

Browser tidak tahu di mana server backendlabs.id berada. Ia bertanya ke DNS (Domain Name System) — semacam buku telepon raksasa di internet.

Browser → DNS Resolver (biasanya dari ISP atau 1.1.1.1)
         → Root Nameserver → .id Nameserver → backendlabs.id Nameserver
         ← IP Address: 103.28.12.45

DNS mengubah nama domain yang mudah diingat manusia menjadi IP address — alamat numerik yang dipakai komputer untuk saling menemukan. Hasil lookup di-cache di browser, OS, dan DNS resolver sehingga lookup berikutnya lebih cepat.

Langkah 2 — TCP Connection (3-Way Handshake)

Setelah tahu IP address-nya, browser membangun koneksi menggunakan TCP (Transmission Control Protocol). TCP memastikan data terkirim dengan benar dan berurutan, melalui jabat tangan tiga langkah:

Browser  →  [SYN]          →  Server    "Hei, saya mau konek"
Browser  ←  [SYN-ACK]      ←  Server    "Oke, saya siap"
Browser  →  [ACK]          →  Server    "Siap, kita mulai"

Seluruh handshake ini selesai dalam hitungan milidetik, tapi latency jaringan tetap berpengaruh — ini kenapa memilih server yang dekat secara geografis penting untuk performa.

Langkah 3 — TLS Handshake (khusus HTTPS)

Untuk HTTPS, ada lapisan tambahan: TLS (Transport Layer Security). Setelah koneksi TCP terbentuk, browser dan server bernegosiasi enkripsi:

Browser  →  "Saya support TLS 1.3, ini cipher yang bisa saya pakai"
Server   ←  "Oke pakai TLS 1.3 + AES-256. Ini sertifikat SSL saya."
Browser  →  [verifikasi sertifikat ke Certificate Authority]
Browser  →  "Sertifikat valid. Mari enkripsi komunikasi kita."

Setelah handshake selesai, semua data yang dikirim terenkripsi. Bahkan ISP atau siapapun yang "menyadap" jaringan hanya melihat data yang tidak bisa dibaca.

Langkah 4 — HTTP Request

Browser mengirimkan request:

GET / HTTP/2
Host: backendlabs.id
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Accept: text/html,application/xhtml+xml
Accept-Language: id-ID,id;q=0.9,en;q=0.8

Langkah 5 — HTTP Response

Server membalas dengan mengirimkan halaman web:

HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 12453
Cache-Control: public, max-age=3600
 
<!DOCTYPE html>
<html lang="id">...</html>

Langkah 6 — Render

Browser menerima HTML, lalu meminta CSS, JavaScript, gambar, dan aset lainnya (masing-masing HTTP request terpisah), kemudian merender halaman yang kamu lihat.

HTTP vs HTTPS

Satu huruf S membuat perbedaan besar:

HTTP — komunikasi plain text. Siapapun yang ada di jaringan yang sama (misalnya WiFi kafe) bisa membaca semua data yang dikirimkan, termasuk password dan token.

HTTPS — komunikasi dienkripsi dengan TLS. Data tidak bisa dibaca meski disadap.

Browser modern menampilkan ikon gembok untuk HTTPS dan peringatan "Not Secure" untuk HTTP. Selalu gunakan HTTPS untuk semua aplikasi — terutama yang menangani data pengguna.

HTTP/1.1, HTTP/2, HTTP/3

Protokol HTTP sudah berkembang:

HTTP/1.1 — satu request per koneksi TCP (atau pipeline yang jarang bekerja sempurna). Browser biasanya membuka 6 koneksi paralel per domain sebagai workaround.

HTTP/2 — multiplexing: banyak request dalam satu koneksi TCP secara bersamaan. Header dikompresi dengan HPACK. Ini yang dipakai di sebagian besar website modern saat ini.

HTTP/3 — mengganti TCP dengan QUIC (berbasis UDP). Lebih cepat terutama pada koneksi yang tidak stabil (mobile), lebih tahan terhadap packet loss. Masih dalam adopsi.

Sebagai backend developer, kamu biasanya tidak perlu mengimplementasikan HTTP/2 atau HTTP/3 secara manual — Nginx atau reverse proxy yang menanganinya.


Bab 2: HTTP: Bahasa Komputer di Internet

Anatomi HTTP Request

Setiap request terdiri dari tiga bagian utama:

[Method] [Path] HTTP/[version]           ← Request Line
[Header-Name]: [Header-Value]            ← Headers (satu per baris)
                                         ← Baris kosong (memisahkan header dan body)
[Body]                                   ← Body (opsional)

Contoh request login:

POST /api/v1/auth/login HTTP/1.1
Host: api.backendlabs.id
Content-Type: application/json
Content-Length: 56
Authorization: Bearer eyJhbGci...
Accept: application/json
 
{"email":"rinaldy@email.com","password":"secret123"}

Komponen-komponennya:

  • POST — method
  • /api/v1/auth/login — path (endpoint)
  • HTTP/1.1 — versi protokol
  • Host sampai Accept — headers (metadata)
  • {"email":...} — body (data yang dikirim)

Anatomi HTTP Response

HTTP/[version] [Status Code] [Reason Phrase]  ← Status Line
[Header-Name]: [Header-Value]                 ← Headers
                                              ← Baris kosong
[Body]                                        ← Body (opsional)

Contoh response sukses:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 287
X-Request-Id: req_abc123
 
{
  "success": true,
  "data": {
    "user": { "id": 1, "name": "Rinaldy", "email": "rinaldy@email.com" },
    "accessToken": "eyJhbGci...",
    "refreshToken": "dGhpcyBpcy..."
  }
}

Anatomy URL Lengkap

https://api.backendlabs.id:443/v1/products?category=backend&sort=price&page=2#results
│       │                  │   │           │                                    │
│       │                  │   │           └── Query String                     │
│       │                  │   └── Path                                         │
│       │                  └── Port (443 = HTTPS default, bisa dihilangkan)     │
│       └── Host (domain)                                                       │
└── Scheme                                                                      └── Fragment (tidak dikirim ke server)

Query string dimulai dengan ? dan berisi pasangan key=value yang dipisahkan &. Digunakan untuk filter, sorting, pagination — data yang tidak mengubah state server (hanya untuk GET).


Bab 3: HTTP Methods: Kata Kerja di API

Mengapa Ada Banyak Method?

HTTP methods menjelaskan apa yang ingin kamu lakukan terhadap sebuah resource. URL adalah benda (apa yang diakses), method adalah kata kerja (apa yang dilakukan).

Tanpa method yang berbeda, server tidak bisa membedakan apakah kamu ingin membaca produk atau menghapus produk — keduanya bisa dikirim ke URL yang sama (/api/products/5).

GET — Ambil Data

Digunakan untuk membaca data. Request GET tidak boleh mengubah apapun di server.

GET /api/v1/products HTTP/1.1           ← semua produk
GET /api/v1/products/42 HTTP/1.1        ← produk dengan ID 42
GET /api/v1/products?category=backend   ← filter by kategori

Karakteristik GET:

  • Tidak punya body
  • Parameter dikirim via query string
  • Bisa di-cache oleh browser dan CDN
  • Safe — tidak mengubah state server
  • Idempotent — memanggil berkali-kali menghasilkan respons yang sama

POST — Buat Data Baru

Digunakan untuk membuat resource baru atau mengirimkan data yang diproses server.

POST /api/v1/products HTTP/1.1
Content-Type: application/json
 
{
  "name": "Ebook Docker Backend",
  "price": 99000,
  "category": "backend"
}

Karakteristik POST:

  • Punya body berisi data
  • Tidak idempotent — mengirim dua kali → buat dua resource berbeda
  • Tidak bisa di-cache
  • Response biasanya: 201 Created + header Location yang menunjuk ke resource baru

PUT — Ganti Keseluruhan

Digunakan untuk mengganti seluruh representasi resource. Kirim semua field.

PUT /api/v1/products/42 HTTP/1.1
Content-Type: application/json
 
{
  "name": "Ebook Docker Backend — Edisi Revisi",
  "price": 119000,
  "category": "backend",
  "description": "Deskripsi lengkap baru..."
}

Jika kamu hanya kirim { "price": 119000 } via PUT, field lainnya bisa terhapus tergantung implementasi server.

PATCH — Update Sebagian

Digunakan untuk memodifikasi resource secara parsial — hanya field yang berubah.

PATCH /api/v1/products/42 HTTP/1.1
Content-Type: application/json
 
{ "price": 119000 }

Gunakan PATCH untuk update sehari-hari. PUT hanya saat memang ingin replace seluruh resource.

DELETE — Hapus

Digunakan untuk menghapus resource.

DELETE /api/v1/products/42 HTTP/1.1

Response biasanya 204 No Content (sukses, tidak ada body) atau 200 OK dengan pesan konfirmasi.

Ringkasan: Safe & Idempotent

Safe — tidak mengubah state server (bisa dipanggil tanpa efek samping). Idempotent — memanggil N kali menghasilkan efek yang sama seperti memanggil 1 kali.

MethodBodySafeIdempotentResponse sukses
GET200 OK
POST201 Created
PUT200 OK
PATCH✗ (umumnya)200 OK
DELETE204 No Content

Bab 4: Status Codes yang Harus Kamu Hafal

Status code adalah angka tiga digit yang memberitahu client apakah requestnya berhasil dan apa yang terjadi di server. Digit pertama menunjukkan kategori.

2xx — Sukses

Request berhasil diproses.

CodeTextKapan dipakai
200OKRequest berhasil — respons standar untuk GET, PUT, PATCH
201CreatedResource baru berhasil dibuat (POST)
202AcceptedRequest diterima tapi belum selesai diproses (async job)
204No ContentBerhasil, tidak ada data yang dikembalikan (DELETE, PATCH tanpa body)

3xx — Redirect

Client perlu melakukan request ke URL lain.

CodeTextKapan dipakai
301Moved PermanentlyURL sudah pindah permanen — browser akan update bookmark
302FoundRedirect sementara — browser tidak update bookmark
304Not ModifiedResource tidak berubah, gunakan cache yang ada

4xx — Error dari Client

Client mengirim request yang bermasalah. Ini bukan kesalahan server.

CodeTextKapan dipakai
400Bad RequestRequest tidak valid: format JSON salah, field kurang/salah tipe
401UnauthorizedBelum autentikasi — token tidak ada, expired, atau invalid
403ForbiddenSudah autentikasi tapi tidak punya izin untuk resource ini
404Not FoundResource tidak ditemukan di server
405Method Not AllowedMethod tidak didukung untuk endpoint ini
409ConflictKonflik data: email sudah terdaftar, duplicate entry
410GoneResource pernah ada tapi sudah dihapus permanen
422Unprocessable EntityData bisa di-parse tapi gagal validasi bisnis
429Too Many RequestsRate limit terlampaui — coba lagi nanti

5xx — Error dari Server

Server gagal memproses request yang valid. Ini kesalahan server, bukan client.

CodeTextKapan dipakai
500Internal Server ErrorError tak terduga — bug di kode, exception tidak tertangani
502Bad GatewayServer upstream (database, microservice) tidak merespons
503Service UnavailableServer kelebihan beban atau sedang maintenance
504Gateway TimeoutUpstream tidak merespons dalam waktu yang ditentukan

Perbedaan yang Sering Membingungkan

400 vs 422: Gunakan 400 untuk request yang tidak bisa diparsing sama sekali (JSON malformed). Gunakan 422 untuk data yang valid secara format tapi gagal validasi bisnis (email format benar tapi domain tidak valid, harga negatif).

401 vs 403:

401 Unauthorized → "Siapa kamu? Tolong buktikan identitasmu dulu."
403 Forbidden    → "Saya tahu kamu siapa, tapi kamu tidak boleh masuk sini."

Login user biasa lalu akses /api/admin/users → 403, bukan 401.

404 vs 410: Gunakan 410 Gone jika resource pernah ada dan sengaja dihapus permanen. 404 untuk resource yang memang tidak pernah ada atau tidak ditemukan.

Error Response yang Baik

Jangan hanya kembalikan status code — sertakan detail yang membantu developer debug:

// ✗ Kurang informatif
HTTP 400 Bad Request
{}
 
// ✓ Informatif
HTTP 422 Unprocessable Entity
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Beberapa field tidak valid",
    "details": [
      { "field": "email", "message": "Format email tidak valid" },
      { "field": "price", "message": "Harga harus angka positif" }
    ]
  }
}

Bab 5: Headers: Metadata di Setiap Request

Apa Itu Header?

Header adalah metadata yang menyertai setiap HTTP request dan response — informasi tambahan di luar body. Format: Nama: Nilai. Tidak case-sensitive untuk nama.

Headers Request Penting

Content-Type — format data di body:

Content-Type: application/json
Content-Type: multipart/form-data; boundary=----FormBoundary7MA4YWxkTrZu0gW
Content-Type: application/x-www-form-urlencoded

Authorization — token autentikasi:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Basic dXNlcjpwYXNzd29yZA==   ← Base64(user:password)
Authorization: ApiKey sk-abc123xyz

Accept — format response yang diinginkan:

Accept: application/json
Accept: text/html, application/xhtml+xml, */*

Content-Length — ukuran body dalam bytes:

Content-Length: 156

Accept-Language — preferensi bahasa:

Accept-Language: id-ID, id;q=0.9, en;q=0.8

Headers Response Penting

Content-Type — format data yang dikembalikan:

Content-Type: application/json; charset=utf-8
Content-Type: text/html; charset=utf-8
Content-Type: image/png

Location — URL resource yang baru dibuat (bersama 201 Created):

HTTP/1.1 201 Created
Location: /api/v1/products/43

Cache-Control — instruksi caching:

Cache-Control: no-cache           ← selalu validasi ke server sebelum gunakan cache
Cache-Control: no-store           ← jangan cache sama sekali (data sensitif)
Cache-Control: max-age=3600       ← cache boleh dipakai sampai 1 jam
Cache-Control: public, max-age=86400   ← bisa di-cache CDN selama 24 jam

ETag — "sidik jari" versi resource — digunakan untuk conditional requests:

ETag: "abc123def456"

Client bisa kirim If-None-Match: "abc123def456" di request berikutnya — server akan balas 304 Not Modified kalau belum berubah, sehingga menghemat bandwidth.

Set-Cookie — menyimpan cookie di browser:

Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Strict; Max-Age=86400

Security Headers

Server sebaiknya mengirimkan headers keamanan untuk melindungi dari serangan umum:

X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc123'
Referrer-Policy: strict-origin-when-cross-origin

CORS: Kenapa Browser Memblokir Request?

CORS (Cross-Origin Resource Sharing) adalah mekanisme keamanan browser yang mencegah JavaScript di app.backendlabs.id untuk secara diam-diam mengakses api.otherdomain.com.

"Origin" didefinisikan oleh kombinasi: scheme + host + port. Jadi:

  • https://backendlabs.id dan https://api.backendlabs.id → berbeda origin
  • http://backendlabs.id dan https://backendlabs.id → berbeda origin (scheme beda)
  • https://backendlabs.id:3000 dan https://backendlabs.id:4000 → berbeda origin (port beda)

Preflight Request: Untuk request yang "tidak sederhana" (menggunakan method non-GET/POST, atau header custom), browser otomatis mengirimkan request OPTIONS terlebih dahulu untuk bertanya apakah cross-origin request diizinkan:

OPTIONS /api/v1/products HTTP/1.1
Origin: https://backendlabs.id
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

Server perlu merespons dengan headers yang mengizinkan:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://backendlabs.id
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400   ← cache preflight response 24 jam

Di Node.js/Express, cukup pakai package cors:

import cors from 'cors';
 
app.use(cors({
  origin: ['https://backendlabs.id', 'https://www.backendlabs.id'],
  methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,   // izinkan cookies/auth header
}));

Penting: CORS dijalankan oleh browser — bukan server. Tools seperti curl dan Postman tidak mengikuti CORS, sehingga request mereka selalu berhasil tanpa peduli header CORS. CORS hanya relevan ketika JavaScript di browser yang mengirimkan request.


Bab 6: JSON: Format Data di Web Modern

Mengapa JSON?

Sebelum JSON populer, XML adalah format standar. Tapi XML verbose dan susah di-parse. JSON (JavaScript Object Notation) menggantinya karena:

  • Ringkas dan mudah dibaca manusia
  • Natively didukung JavaScript (JSON.parse, JSON.stringify)
  • Library tersedia di hampir semua bahasa pemrograman
  • Ukuran payload lebih kecil dari XML untuk data yang sama

Sintaks JSON

JSON hanya punya 6 tipe data:

{
  "string":   "Hello, World!",
  "number":   42,
  "float":    3.14159,
  "boolean":  true,
  "null_val": null,
  "array":    [1, "dua", true, null],
  "object":   {
    "nested_key": "nested_value"
  }
}

Aturan yang sering dilupakan:

  • Key harus pakai double quote "key" — single quote 'key' tidak valid
  • String harus pakai double quote
  • Tidak boleh trailing comma: [1, 2, 3,] ← tidak valid JSON (tapi valid JavaScript!)
  • Tidak ada komentar (// atau /* */) dalam JSON murni
  • Angka tidak boleh diawali nol: 0123 ← tidak valid

JSON di JavaScript

// Parse JSON string menjadi JavaScript object
const jsonString = '{"name":"Rinaldy","age":28}';
const obj = JSON.parse(jsonString);
console.log(obj.name);  // "Rinaldy"
 
// Konversi JavaScript object menjadi JSON string
const data = { name: "Rinaldy", skills: ["Node.js", "PostgreSQL"] };
const json = JSON.stringify(data);
// '{"name":"Rinaldy","skills":["Node.js","PostgreSQL"]}'
 
// Dengan indentasi untuk debugging
const prettyJson = JSON.stringify(data, null, 2);
/*
{
  "name": "Rinaldy",
  "skills": [
    "Node.js",
    "PostgreSQL"
  ]
}
*/

Pitfall: JSON.parse Bisa Throw Error

Selalu wrap JSON.parse dalam try/catch kalau input tidak terjamin valid:

// ✗ Berbahaya
const data = JSON.parse(req.body);  // crash jika body bukan JSON valid
 
// ✓ Aman
try {
  const data = JSON.parse(req.body);
} catch (err) {
  return res.status(400).json({ error: 'Invalid JSON' });
}
 
// Lebih baik: pakai middleware Express yang otomatis handle ini
app.use(express.json());  // sudah ada error handling bawaan

Date & Time di JSON

JSON tidak punya tipe Date. Gunakan string format ISO 8601:

{
  "createdAt": "2026-06-29T10:30:00.000Z",
  "expiresAt": "2026-07-06T10:30:00.000Z"
}

Huruf Z di akhir berarti UTC (Coordinated Universal Time). Selalu simpan dan kirim timestamp dalam UTC — biarkan frontend yang mengkonversi ke timezone lokal user.

// Buat timestamp UTC
new Date().toISOString()        // "2026-06-29T10:30:00.000Z"
 
// Parse ISO string
new Date("2026-06-29T10:30:00.000Z")

API Response Pattern yang Konsisten

API yang baik punya struktur response yang konsisten — memudahkan frontend memproses apapun yang dikembalikan:

// ✓ Single resource
{
  "success": true,
  "data": {
    "id": 42,
    "name": "Ebook Docker"
  }
}
 
// ✓ Collection dengan pagination
{
  "success": true,
  "data": [
    { "id": 1, "name": "Ebook HTTP" },
    { "id": 2, "name": "Ebook Git" }
  ],
  "meta": {
    "total": 23,
    "page": 1,
    "perPage": 10,
    "totalPages": 3
  }
}
 
// ✓ Error
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Produk dengan ID 42 tidak ditemukan"
  }
}

Bab 7: REST: Konvensi Membangun API

Apa Itu REST?

REST (Representational State Transfer) bukan teknologi atau protokol — ini adalah arsitektur gaya (architectural style) yang mendefinisikan konvensi untuk membangun API di atas HTTP.

API yang mengikuti konvensi REST disebut RESTful API. Hampir semua API publik (GitHub, Stripe, Twitter) mengikuti REST.

Prinsip Utama REST

1. Resources, bukan aksi

URL mewakili benda (resource), bukan aksi. Method HTTP yang menunjukkan aksi.

// ✗ Bukan REST — URL berisi aksi
GET  /getProducts
POST /createProduct
POST /deleteProduct/42

// ✓ REST — URL adalah resource, method adalah aksi
GET    /products          ← ambil semua produk
POST   /products          ← buat produk baru
GET    /products/42       ← ambil produk #42
PUT    /products/42       ← ganti produk #42
PATCH  /products/42       ← update sebagian produk #42
DELETE /products/42       ← hapus produk #42

2. Gunakan noun jamak

Gunakan bentuk jamak yang konsisten untuk resource collection:

/products     ← bukan /product
/users        ← bukan /user
/categories   ← bukan /category

3. Nested resources untuk relasi

GET /users/5/orders           ← semua order milik user #5
GET /users/5/orders/12        ← order #12 milik user #5
POST /products/42/reviews     ← buat review untuk produk #42

Hindari nesting lebih dari 2 level — URL jadi terlalu panjang dan susah dipakai.

4. Query string untuk filter, sort, pagination

GET /products?category=backend          ← filter
GET /products?sort=price&order=asc      ← sort
GET /products?page=2&limit=10           ← pagination
GET /products?q=docker                  ← search
GET /products?category=backend&sort=price&page=1&limit=10  ← kombinasi

Versioning API

API berubah seiring waktu. Tanpa versioning, perubahan bisa merusak client yang sudah ada. Cara paling umum: versi di URL.

GET /api/v1/products    ← version 1
GET /api/v2/products    ← version 2 (mungkin ada perubahan response format)

Alternatif yang lebih "pure REST": versi di header:

Accept: application/vnd.backendlabs.v2+json

Tapi versi di URL lebih mudah di-debug dan lebih umum dipakai.

Idempotency Key untuk POST

POST tidak idempotent — request yang sama dua kali bisa membuat dua resource. Untuk operasi penting (pembayaran, pengiriman email), gunakan idempotency key:

POST /api/v1/payments HTTP/1.1
Idempotency-Key: uuid-abc-123-def-456
 
{ "amount": 99000, "product_id": 42 }

Server menyimpan key ini dan jika menerima request dengan key yang sama, mengembalikan response yang sama tanpa memproses ulang. Ini mencegah double-charge jika client mengirim request dua kali karena network timeout.

Membaca Dokumentasi API

Hampir semua API publik punya dokumentasi. Kenali format yang umum:

Format OpenAPI/Swagger:

GET /products/{id}:
  summary: Get product by ID
  parameters:
    - name: id
      in: path
      required: true
      schema:
        type: integer
  responses:
    '200':
      description: Successful response
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Product'
    '404':
      description: Product not found

Ketika membaca docs API, perhatikan:

  1. Base URL — prefix semua endpoint, misal https://api.stripe.com/v1
  2. Authentication — cara autentikasi (API key di header, Bearer token, dll)
  3. Rate limits — berapa request per detik/menit yang diizinkan
  4. Response format — struktur JSON yang dikembalikan
  5. Error codes — error code spesifik yang bisa dikembalikan API tersebut

Bab 8: Coba Sendiri: curl & Hoppscotch

curl — HTTP Client di Terminal

curl adalah tool command-line untuk mengirimkan HTTP request. Sudah terinstall di Mac dan Linux.

GET request:

# Request sederhana
curl https://api.github.com/users/torvalds
 
# Dengan formatting JSON (butuh python3)
curl https://api.github.com/users/torvalds | python3 -m json.tool
 
# Hanya tampilkan status code
curl -s -o /dev/null -w "%{http_code}" https://backendlabs.id/api/health

POST dengan JSON body:

curl -X POST \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer YOUR_TOKEN" \
     -d '{"title":"Belajar HTTP","body":"Ini isi postnya"}' \
     https://jsonplaceholder.typicode.com/posts

Flag-flag penting:

-X METHOD      # specify HTTP method: -X POST, -X DELETE, dsb
-H "Key: Val"  # tambahkan header
-d 'data'      # request body (otomatis set -X POST)
-s             # silent mode: sembunyikan progress bar
-v             # verbose: tampilkan request + response headers
-i             # include response headers di output
-o file.json   # simpan response ke file
-L             # ikuti redirect
--max-time 10  # timeout setelah 10 detik

Lihat full request dan response:

curl -sv https://api.github.com/users/torvalds 2>&1 | head -60
# Prefix > = request yang dikirim
# Prefix < = response yang diterima

Upload file:

curl -X POST \
     -H "Authorization: Bearer TOKEN" \
     -F "file=@/path/to/foto.jpg" \
     -F "description=Profile photo" \
     https://api.example.com/upload

API Publik untuk Latihan

Gunakan API publik ini untuk bereksperimen tanpa perlu akun:

# JSONPlaceholder — fake REST API untuk testing
curl https://jsonplaceholder.typicode.com/posts/1
curl https://jsonplaceholder.typicode.com/users
curl -X POST -H "Content-Type: application/json" \
     -d '{"title":"test","body":"isi","userId":1}' \
     https://jsonplaceholder.typicode.com/posts
 
# Open Meteo — cuaca tanpa API key
curl "https://api.open-meteo.com/v1/forecast?latitude=-6.2&longitude=106.8&current=temperature_2m"
 
# GitHub API — data public repository
curl https://api.github.com/repos/expressjs/express
curl https://api.github.com/repos/expressjs/express/releases/latest | python3 -m json.tool
 
# IP Info
curl https://ipapi.co/json/

Hoppscotch — GUI untuk HTTP Request

Hoppscotch adalah alternatif Postman open-source yang bisa dipakai langsung di browser tanpa install. Fitur utamanya:

Kirim request:

  1. Buka hoppscotch.io
  2. Pilih method (GET, POST, dll) dari dropdown
  3. Masukkan URL
  4. Tambahkan headers di tab "Headers"
  5. Tambahkan body JSON di tab "Body" → pilih "JSON"
  6. Klik "Send"

Simpan dan organisir requests:

  • Gunakan Collections untuk mengelompokkan request berdasarkan project
  • Bisa export collection sebagai JSON dan dibagikan ke tim

Environment Variables:

base_url = https://api.backendlabs.id
token    = eyJhbGci...

Lalu gunakan di URL: {{base_url}}/products dan di header: Authorization: Bearer {{token}}

Latihan Terstruktur

Latihan 1 — GET:

Method: GET
URL: https://jsonplaceholder.typicode.com/todos?userId=1&completed=false

Perhatikan: query string untuk filter, response array of objects, status 200.

Latihan 2 — POST:

Method: POST
URL: https://jsonplaceholder.typicode.com/posts
Headers: Content-Type: application/json
Body:
{
  "title": "Ebook BackendLabs",
  "body": "Saya sedang belajar HTTP",
  "userId": 1
}

Perhatikan: response 201 Created, server assign id secara otomatis.

Latihan 3 — 404:

Method: GET
URL: https://jsonplaceholder.typicode.com/posts/99999

Perhatikan: response 404 Not Found, body {}.

Latihan 4 — Error parsing: Coba kirim JSON yang tidak valid (tambahkan koma di akhir):

{ "name": "test", }

Perhatikan status 400 atau 422 tergantung implementasi server.


Penutup

Mental model yang kamu bangun di e-book ini akan terus kamu pakai seumur karir sebagai backend developer. Setiap kali kamu debug kenapa API tidak merespons, kenapa CORS error, atau kenapa request gagal — kamu akan kembali ke dasar-dasar ini.

Checklist Pemahaman

  • Bisa menjelaskan apa yang terjadi saat browser membuka URL — dari DNS sampai render
  • Mengerti perbedaan HTTP dan HTTPS, dan kenapa HTTPS wajib
  • Tahu kapan menggunakan GET, POST, PUT, PATCH, DELETE
  • Bisa membedakan 401 vs 403, 400 vs 422, 404 vs 410
  • Mengerti fungsi Content-Type, Authorization, Cache-Control, dan CORS headers
  • Bisa menulis dan membaca JSON yang valid, termasuk handling Date
  • Mengerti prinsip URL design di REST: noun jamak, nested resource, query string untuk filter
  • Bisa mengirim HTTP request dengan curl: GET, POST, dengan headers dan body
  • Bisa membaca dokumentasi API dan memahami endpoint, params, dan response schema

Langkah Selanjutnya

  • E-book #01 (Git & GitHub) — sebelum menulis kode apapun, pelajari cara melacak perubahannya
  • E-book #02 (REST API Node.js) — kamu sudah tahu HTTP bekerja, sekarang saatnya membangun server yang melayaninya