curl — Deep Dive — Terminal

curl adalah Swiss Army knife HTTP. Lebih dari sekadar "download file" — ini alat debugging API yang wajib dikuasai developer. Basic request: curl…

curl mengirim request HTTP dari terminal lalu mencetak response-nya apa adanya. Ini cara paling cepat mengetes API tanpa bikin halaman web. Bayangkan kirim paket lewat kurir: kamu menentukan jenis kirimannya (method: GET, POST, DELETE), label di bungkusnya (header, misalnya "isinya JSON"), dan isinya (body). Kurirnya pulang membawa balasan: kode status, label balasan, dan isi balasan.

🧪 Tebakan cepat: API di http://localhost:3000/users cuma mau menerima JSON. Kamu menjalankan curl -d '{"name":"budi"}' http://localhost:3000/users. User budi berhasil dibuat? Tebak dulu, jawabannya ada di bagian "Kirim data: -d dan Content-Type".

Request paling sederhana: GET

Tanpa flag apa pun, curl mengirim GET dan mencetak body response-nya:

$ curl http://localhost:3000/users
[{"id":1,"name":"ani"}]
$ curl -i http://localhost:3000/users
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 24

[{"id":1,"name":"ani"}]

Pilih method: -X

-X (huruf X besar) menentukan method-nya. Tanpa -X, method-nya GET.

$ curl -i -X DELETE http://localhost:3000/users
HTTP/1.1 405 Method Not Allowed
Allow: GET, POST
Content-Type: application/json
Content-Length: 31

{"error":"Method Not Allowed"}

Server menolak dengan 405 dan memberi tahu lewat header Allow method apa saja yang boleh. Status yang diawali 2 berarti berhasil, 4 berarti salah di request-mu, 5 berarti server-nya yang bermasalah.

Kirim data: -d dan Content-Type

-d (data) mengisi body dan otomatis mengubah method jadi POST, jadi -X POST gak wajib. Body-nya dikirim persis seperti yang kamu tulis. Masalahnya ada di label: tanpa -H, curl memberi label Content-Type: application/x-www-form-urlencoded, yaitu "isinya data formulir", walaupun yang kamu tulis JSON.

$ curl -i -d '{"name":"budi"}' http://localhost:3000/users
HTTP/1.1 415 Unsupported Media Type
Content-Type: application/json
Content-Length: 50

{"error":"Content-Type must be application/json"}
$ curl -i -X POST -H "Content-Type: application/json" -d '{"name":"budi"}' http://localhost:3000/users
HTTP/1.1 201 Created
Content-Type: application/json
Content-Length: 23

{"id":2,"name":"budi"}

Jadi tebakannya: gagal. Server menerima body yang benar, tapi labelnya bilang formulir, dan API yang cuma mau JSON membalas 415 Unsupported Media Type. Itu jawaban tebakannya. Perintah kedua adalah pola standar POST JSON:

curl versi 7.82 ke atas juga punya --json '{"name":"budi"}', singkatan untuk POST dengan Content-Type dan Accept JSON sekaligus.

Intip semuanya: -v

-v (verbose) menampilkan request yang benar-benar dikirim dan response yang diterima. Ini alat debug API paling dasar:

$ curl -v -d '{"name":"budi"}' http://localhost:3000/users
*   Trying [::1]:3000...
* Connected to localhost (::1) port 3000
> POST /users HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/8.5.0
> Accept: */*
> Content-Length: 15
> Content-Type: application/x-www-form-urlencoded
> 
< HTTP/1.1 415 Unsupported Media Type
< Content-Type: application/json
< Content-Length: 50
< 
{"error":"Content-Type must be application/json"}
* Connection #0 to host localhost left intact

Flag lain yang sering dipakai

Flag Gunanya
-s silent, sembunyikan progress bar (enak di script)
-o hasil.json simpan body ke file, bukan ke layar
-O simpan ke file dengan nama dari URL
-L ikuti redirect (status 301, 302) sampai alamat akhirnya
-I kirim HEAD, cuma minta header tanpa body
-w "%{http_code}\n" cetak kode status setelah response
-u budi:rahasia login Basic Auth
-H "Authorization: Bearer $TOKEN" kirim token
-k lewati pemeriksaan sertifikat TLS (bahaya, baca jebakannya)

Contoh cek cepat apakah server hidup: curl -s -o /dev/null -w "%{http_code}\n" http://localhost:3000/users mencetak 200 saja.

⚠️ Jebakan yang sering ketemu

TL;DR: curl URL mengirim GET dan mencetak body. -X menentukan method, -H "Nama: nilai" menambah header, -d mengisi body dan otomatis membuat method jadi POST (kalau -X gak ditulis). Body dikirim apa adanya, tapi labelnya formulir, jadi untuk JSON tambahkan -H "Content-Type: application/json" dan bungkus JSON dengan tanda kutip satu. -i menampilkan status dan header response, -v menampilkan semua yang dikirim (>) dan diterima (<). URL adalah kata yang bukan flag dan bukan pasangan flag. Jangan pakai -k di production.

Yang akan kamu pelajari