gon: Bikin HTTP Client Sendiri di Terminal, dan Apa yang Saya Pelajari
Saya termasuk orang yang betah di terminal. Editor, git, deploy, log — hampir semuanya saya kerjakan tanpa lepas dari shell. Tapi ada satu hal yang selalu memaksa saya keluar dari sana: ngetes API.
Buka Postman, tunggu loading, klik sana-sini, bikin tab baru. Atau pakai curl — yang ujung-ujungnya jadi baris panjang penuh -H dan -d yang harus saya ketik ulang tiap kali. Untuk request yang sama. Berkali-kali.
Lama-lama gatel. Kenapa nggak bikin sendiri yang sesuai cara kerja saya? Dari rasa gatel itulah lahir gon — sebuah HTTP client interaktif untuk orang yang cinta terminal.
Ide-nya: REPL, bukan satu-shot
Hal pertama yang saya putuskan: gon harus terasa seperti tinggal di dalamnya, bukan dipanggil sekali lalu selesai. Jadi inti gon adalah sebuah REPL — kamu masuk, lalu mengirim request satu demi satu sambil melihat respons yang langsung berwarna.
BASH$ gon gon(my-api)> get /todos/1 200 OK (84ms) { "userId": 1, "id": 1, "title": "delectus aut autem", "completed": false }
Status code-nya berwarna sesuai kelasnya (hijau untuk 2xx, kuning untuk 4xx, merah untuk 5xx), waktu eksekusinya juga berwarna sesuai cepat-lambatnya, dan JSON-nya di-pretty-print lengkap dengan syntax highlighting. Semua tanpa pindah ke aplikasi lain.
Tapi saya juga tidak mau kehilangan kepraktisan curl untuk scripting. Jadi gon punya one-shot mode: panggil langsung dari shell, jalan, selesai.
BASHgon get https://api.example.com/users
Satu tool, dua cara pakai. Itu prinsip yang saya pegang dari awal.
Workspace: satu folder yang bisa dibagikan
Di sinilah gon mulai jadi menarik buat saya. Saya tidak mau konfigurasi tersembunyi di suatu file dotfile yang cuma ada di laptop saya. Saya mau hasil kerja saya bisa diserahkan ke orang lain.
Jalankan gon init di sebuah folder, dan folder itu menjadi sebuah workspace — sebuah proyek yang self-contained. Semua yang dibuat gon adalah file teks biasa di dalam folder tersebut:
BASHmy-api/ ├── workspace.yml # default header, query, base path ├── environments/ │ ├── local.yml # base_url + variabel │ └── prod.yml ├── auth/ │ ├── collection.yml # default untuk semua request di bawahnya │ └── login.yml # satu request tersimpan └── todos/ └── create.yml
Karena semuanya cuma file YAML, seluruh folder bisa di-commit ke git atau diserahkan ke rekan frontend — dan mereka langsung dapat semua environment, collection, dan request yang sama persis. Tidak ada langkah "ekspor-impor", tidak ada yang ketinggalan. Folder-nya adalah artefaknya.
Environments dan {{variabel}}
Setiap proyek pasti punya local, dev, dan prod. Saya tidak mau menyalin-tempel URL dan token tiap kali berganti target. Jadi gon punya environments: kumpulan variabel bernama, masing-masing dengan base URL-nya sendiri.
YAML# environments/dev.yml name: dev base_url: https://api.dev.example.com variables: token: abc123 user_id: "42"
Di mana saja — URL, header, query, body — kamu bisa menyebut variabel dengan {{name}}:
YAMLheaders: Authorization: Bearer {{token}}
Ganti environment cukup dengan gon env use prod, atau timpa sekali jalan dengan gon get /users --env prod. Dan ini bagian yang saya suka: pilihan environment aktif disimpan di .gon/active-env yang gitignored, jadi tiap developer di tim bisa memilih environment-nya masing-masing tanpa saling menimpa.
Satu keputusan desain kecil yang saya banggakan: kalau ada {{variabel}} yang tidak terselesaikan, gon gagal lebih awal dengan pesan yang menyebut nama variabel yang hilang — sebelum request dikirim. Lebih baik error yang jelas daripada request diam-diam terkirim dengan token kosong.
Kenapa Go dan hexagonal architecture
Saya pilih Go karena binary tunggal tanpa runtime, cepat, dan enak buat tool CLI. Tapi keputusan yang lebih menentukan adalah arsitekturnya.
gon dibangun dengan hexagonal architecture (ports & adapters). Singkatnya: ada inti (core) yang berisi logika domain, dan semua hal di luar — CLI, penyimpanan YAML, pemformatan output — adalah adapter yang nyolok ke inti lewat port (interface). Arah ketergantungannya selalu menunjuk ke dalam, ke arah core.
Buat proyek sekecil ini, hexagonal mungkin terdengar berlebihan. Tapi justru itu poinnya buat saya: gon adalah tempat saya melatih disiplin itu di lingkungan yang aman. Hasilnya nyata — logika domain bisa dites tanpa benar-benar mengirim HTTP request atau menyentuh disk, dan menambah perintah baru jadi resep yang berulang dan rapi. Mengganti format penyimpanan dari YAML ke yang lain pun tidak akan menyentuh satu baris pun logika inti.
Yang saya pelajari
Membangun gon mengajari saya beberapa hal yang tidak saya duga di awal:
- Desain CLI itu desain produk. Memutuskan
--minimal/--normal/--full, urutan presedensi flag, dan pesan error yang baik ternyata sama pentingnya dengan kode di baliknya. Tool yang bagus terasa "jelas" — dan kejelasan itu hasil banyak keputusan kecil. - Fail-fast lebih ramah daripada terlihat pintar. Menolak request lebih awal dengan pesan yang spesifik menyelamatkan pengguna dari debugging yang membingungkan.
- "Shareable" adalah fitur. Membuat seluruh workspace jadi file teks biasa yang bisa di-commit mengubah gon dari sekadar tool pribadi menjadi sesuatu yang bisa dipakai satu tim.
- Arsitektur yang bersih membayar lebih cepat dari dugaan. Bahkan di proyek kecil, batas-batas yang jelas membuat saya berani menambah fitur tanpa takut merusak yang sudah ada.
Coba sendiri
gon open source dan berlisensi MIT. Di Linux dan macOS, satu baris ini sudah cukup:
BASHcurl -fsSL https://raw.githubusercontent.com/fakhrulnugroho/gon/main/install.sh | bash
Kode, dokumentasi, dan panduan kontribusinya ada di github.com/fakhrulnugroho/gon. Kalau kamu juga termasuk orang yang betah di terminal, saya senang kalau kamu mau mencoba — atau sekadar mengintip kodenya dan memberi masukan.
Kadang proyek terbaik memang berawal dari satu rasa gatel kecil yang akhirnya kamu garuk sendiri.