HTTP adalah protokol yang menggerakkan hampir seluruh komunikasi internet modern: halaman web, API publik, bahkan pembaruan aplikasi ponsel. Library Python menyembunyikan detailnya dengan baik — sampai suatu hari server menjawab 429 dan program kita berhenti bekerja tanpa pesan yang jelas. Pada Chapter ini kita membedah anatomi request dan response HTTP secara langsung, sehingga pesan-pesan seperti itu menjadi informasi yang bisa dibaca, bukan teka-teki.

Anatomi Request dan Response #

Setiap percakapan HTTP terdiri dari dua bagian: request dari klien dan response dari server. Keduanya memiliki struktur yang sama — baris pembuka, daftar header, satu baris kosong, lalu body:

text
REQUEST (dari klien ke server)
GET /v1/users?page=2 HTTP/1.1
Host: api.example.com
User-Agent: belajar-python/1.0
Accept: application/json

RESPONSE (dari server ke klien)
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 87

{"data": [{"id": 1, "nama": "Budi"}]}

Baris pertama request menyatakan method, path beserta query string, dan versi protokol. Baris pertama response menyatakan versi protokol, kode status, dan alasannya. Header berbentuk pasangan Nama: nilai yang memberi metadata — Host wajib ada pada HTTP/1.1, Content-Type memberi tahu format body, Content-Length menyatakan ukuran body dalam byte. Baris kosong menjadi pemisah tegas antara header dan body; tanpa pemisah tersebut server tidak tahu di mana header berakhir.

Method HTTP, Kata Kerja Protokol #

Method menyatakan niat klien kepada server. Lima method berikut menutupi hampir semua pekerjaan sehari-hari:

MethodFungsiBody requestContoh pemakaian
GETMembaca dataUmumnya tidakMengambil daftar produk
POSTMembuat data baruYaMenambah produk ke keranjang
PUTMengganti data secara utuhYaMemperbarui seluruh profil pengguna
PATCHMengubah sebagian dataYaMengubah hanya kolom harga
DELETEMenghapus dataJarangMenghapus satu produk

Method GET, PUT, dan DELETE bersifat idempotent — memanggilnya sekali atau sepuluh kali menghasilkan kondisi akhir yang sama. Method POST tidak: lima kali kirim form pendaftaran berarti lima akun tercipta. Karakter ini penting saat menentukan permintaan mana yang aman diulang, tema yang kita bahas tuntas pada Chapter Timeouts dan Retries.

Status Code dan Keluarganya #

Setiap response membawa kode status tiga digit. Digit pertama menunjukkan keluarga maknanya:

KeluargaArtiAnggota yang sering ditemui
1xxInformasi, proses berlanjut101 Switching Protocols
2xxSukses200 OK, 201 Created, 204 No Content
3xxRedirect, pindah lokasi301 Moved Permanently, 304 Not Modified
4xxSalah di pihak klien400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests
5xxSalah di pihak server500 Internal Server Error, 503 Service Unavailable

Aturan praktisnya: status 4xx berarti kita harus memperbaiki permintaan (misalnya melengkapi token), sedangkan status 5xx berarti masalah ada di sisi server dan mencoba lagi beberapa saat kemudian sering masuk akal.

Anatomi URL #

URL adalah alamat lengkap tujuan request. Module urllib.parse mampu memecahnya menjadi komponen-komponen yang bermakna:

python
from urllib.parse import urlsplit

url = "https://api.example.com:443/v1/users?page=2&limit=10"
bagian = urlsplit(url)

print("scheme  :", bagian.scheme)
print("netloc  :", bagian.netloc)
print("path    :", bagian.path)
print("query   :", bagian.query)

Output yang Dihasilkan:

text
scheme  : https
netloc  : api.example.com:443
path    : /v1/users
query   : page=2&limit=10

Mari kita telaah baris-baris kode di atas:

  1. Baris 1 (from urllib.parse import urlsplit): Kita memuat function urlsplit() yang tugasnya memecah URL, bukan melakukan koneksi jaringan.
  2. Baris 4 (urlsplit(url)): Function tersebut mengembalikan object SplitResult berisi komponen bernama — scheme (protokol), netloc (host dan port), path (lokasi resource), query (parameter setelah tanda ?).
  3. Baris 6-9: Setiap komponen dicetak dengan labelnya; pasangan page=2&limit=10 pada query adalah parameter yang dibaca server untuk menentukan isi response.

Mengintip Percakapan HTTP #

Teori di atas bisa kita saksikan langsung. Standard library memiliki server web siap pakai; buat folder latihan berisi satu file, lalu nyalakan server pada port 8123:

bash
mkdir latihan-http && cd latihan-http
printf "Halo dari server lokal!" > halo.txt
python3 -m http.server 8123

Server tersebut menyajikan file di folder tempat server dijalankan. Biarkan terminal server tetap berjalan, lalu dari folder lain kirim request dengan module http.client:

python
import http.client

koneksi = http.client.HTTPConnection("127.0.0.1", 8123, timeout=3)
koneksi.request("GET", "/halo.txt")

respons = koneksi.getresponse()
print("Status :", respons.status, respons.reason)
print("Tipe   :", respons.getheader("Content-Type"))
print("Isi    :", respons.read().decode("utf-8"))

koneksi.close()

Output yang Dihasilkan:

text
Status : 200 OK
Tipe   : text/plain
Isi    : Halo dari server lokal!

Perintah curl memberi cara yang lebih ringkas dari terminal:

bash
curl -s http://127.0.0.1:8123/halo.txt

Output yang Dihasilkan:

text
Halo dari server lokal!