"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
- Bagaimana Internet Bekerja
- HTTP: Bahasa Komputer di Internet
- HTTP Methods: Kata Kerja di API
- Status Codes yang Harus Kamu Hafal
- Headers: Metadata di Setiap Request
- JSON: Format Data di Web Modern
- REST: Konvensi Membangun API
- 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.8Langkah 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 protokolHostsampaiAccept— 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 kategoriKarakteristik 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+ headerLocationyang 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.1Response 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.
| Method | Body | Safe | Idempotent | Response sukses |
|---|---|---|---|---|
| GET | ✗ | ✓ | ✓ | 200 OK |
| POST | ✓ | ✗ | ✗ | 201 Created |
| PUT | ✓ | ✗ | ✓ | 200 OK |
| PATCH | ✓ | ✗ | ✗ (umumnya) | 200 OK |
| DELETE | ✗ | ✗ | ✓ | 204 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.
| Code | Text | Kapan dipakai |
|---|---|---|
| 200 | OK | Request berhasil — respons standar untuk GET, PUT, PATCH |
| 201 | Created | Resource baru berhasil dibuat (POST) |
| 202 | Accepted | Request diterima tapi belum selesai diproses (async job) |
| 204 | No Content | Berhasil, tidak ada data yang dikembalikan (DELETE, PATCH tanpa body) |
3xx — Redirect
Client perlu melakukan request ke URL lain.
| Code | Text | Kapan dipakai |
|---|---|---|
| 301 | Moved Permanently | URL sudah pindah permanen — browser akan update bookmark |
| 302 | Found | Redirect sementara — browser tidak update bookmark |
| 304 | Not Modified | Resource tidak berubah, gunakan cache yang ada |
4xx — Error dari Client
Client mengirim request yang bermasalah. Ini bukan kesalahan server.
| Code | Text | Kapan dipakai |
|---|---|---|
| 400 | Bad Request | Request tidak valid: format JSON salah, field kurang/salah tipe |
| 401 | Unauthorized | Belum autentikasi — token tidak ada, expired, atau invalid |
| 403 | Forbidden | Sudah autentikasi tapi tidak punya izin untuk resource ini |
| 404 | Not Found | Resource tidak ditemukan di server |
| 405 | Method Not Allowed | Method tidak didukung untuk endpoint ini |
| 409 | Conflict | Konflik data: email sudah terdaftar, duplicate entry |
| 410 | Gone | Resource pernah ada tapi sudah dihapus permanen |
| 422 | Unprocessable Entity | Data bisa di-parse tapi gagal validasi bisnis |
| 429 | Too Many Requests | Rate limit terlampaui — coba lagi nanti |
5xx — Error dari Server
Server gagal memproses request yang valid. Ini kesalahan server, bukan client.
| Code | Text | Kapan dipakai |
|---|---|---|
| 500 | Internal Server Error | Error tak terduga — bug di kode, exception tidak tertangani |
| 502 | Bad Gateway | Server upstream (database, microservice) tidak merespons |
| 503 | Service Unavailable | Server kelebihan beban atau sedang maintenance |
| 504 | Gateway Timeout | Upstream 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-urlencodedAuthorization — token autentikasi:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Basic dXNlcjpwYXNzd29yZA== ← Base64(user:password)
Authorization: ApiKey sk-abc123xyzAccept — format response yang diinginkan:
Accept: application/json
Accept: text/html, application/xhtml+xml, */*Content-Length — ukuran body dalam bytes:
Content-Length: 156Accept-Language — preferensi bahasa:
Accept-Language: id-ID, id;q=0.9, en;q=0.8Headers 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/pngLocation — URL resource yang baru dibuat (bersama 201 Created):
HTTP/1.1 201 Created
Location: /api/v1/products/43Cache-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 jamETag — "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=86400Security 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-originCORS: 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.iddanhttps://api.backendlabs.id→ berbeda originhttp://backendlabs.iddanhttps://backendlabs.id→ berbeda origin (scheme beda)https://backendlabs.id:3000danhttps://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, AuthorizationServer 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 jamDi 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
curldan 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 bawaanDate & 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+jsonTapi 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 foundKetika membaca docs API, perhatikan:
- Base URL — prefix semua endpoint, misal
https://api.stripe.com/v1 - Authentication — cara autentikasi (API key di header, Bearer token, dll)
- Rate limits — berapa request per detik/menit yang diizinkan
- Response format — struktur JSON yang dikembalikan
- 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/healthPOST 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/postsFlag-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 detikLihat full request dan response:
curl -sv https://api.github.com/users/torvalds 2>&1 | head -60
# Prefix > = request yang dikirim
# Prefix < = response yang diterimaUpload file:
curl -X POST \
-H "Authorization: Bearer TOKEN" \
-F "file=@/path/to/foto.jpg" \
-F "description=Profile photo" \
https://api.example.com/uploadAPI 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¤t=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:
- Buka hoppscotch.io
- Pilih method (GET, POST, dll) dari dropdown
- Masukkan URL
- Tambahkan headers di tab "Headers"
- Tambahkan body JSON di tab "Body" → pilih "JSON"
- 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