Saya pernah berada di posisi di mana codebase PHP sudah kepenuhan — fitur baru makin susah ditambah, bug makin sering muncul, dan setiap deploy terasa seperti melempar koin. Bukan karena PHP jelek, tapi karena sistem yang dibangun bertahun-tahun tanpa arsitektur yang jelas akhirnya menyusahkan dirinya sendiri.
Nganu, jadi tulisan ini bukan “Go lebih baik dari PHP” atau “PHP sudah mati”. Bukan. Tulisan ini catatan pengalaman saya melakukan migrasi sistem backend dari PHP (CodeIgniter 3 dan Laravel) ke Go, berdasarkan proyek nyata yang saya kerjakan.
Masalahnya Bukan Bahasa, Tapi Arsitektur #
Sistem yang saya tangani punya profil seperti ini:
- 370+ API endpoint — _ ya, bukan salah ketik_
- 33 database entity yang saling berhubungan
- ~194.000 baris kode PHP yang terdiri dari campuran CodeIgniter 3 dan Laravel
- Testing? Ada, tapi coverage-nya… yah, lebih baik tidak dibahas hehe
Masalah sebenarnya bukan di bahasa pemrogramannya. Masalahnya ada di:
- Tidak ada pemisahan layer — controller langsung query ke database, business logic bercampur dengan presentation logic
- Sulit di-test — kode yang tightly coupled bikin unit testing jadi nightmare
- Developer experience menurun — onboarding developer baru makin lama, bug fix makin berisiko
Intinya, sistem ini butuh bukan sekadar ganti bahasa, tapi re-architect.
Kenapa Go? #
Kalau ditanya kenapa tidak refactor saja di PHP, jawabannya: bisa saja. Tapi dalam kasus ini, ada beberapa alasan kenapa Go jadi pilihan yang lebih tepat:
1. Type Safety Menghemat Waktu Debug #
PHP itu dynamically typed, yang artinya banyak bug baru ketahuan saat runtime. Go dengan static typing-nya menangkap error saat compile time. Sederhana, tapi dampaknya besar — bug yang biasanya baru muncul di production sekarang ketahuan saat build.
2. Concurrency untuk Free #
Sistem ini menangani banyak request simultan — mulai dari tracking GPS real-time hingga report generation. Goroutine di Go membuat concurrent programming jadi jauh lebih simpel dibanding approach lain yang pernah saya coba.
3. Deployment yang Bersih #
Satu binary. Tanpa dependency hell, tanpa composer install di server, tanpa PHP version conflict. Build di lokal, deploy satu file. Done.
4. Performance yang Terukur #
Bukan soal benchmark angka, tapi soal penggunaan resource yang predictable. Memory usage Go yang konsisten membuat kapasitas planning jauh lebih mudah.
Bukan berarti Go sempurna — error handling-nya verbose (semua if err != nil itu… well, you get used to it), dan ecosystem-nya lebih kecil dari PHP. Tapi untuk use case ini, trade-off-nya sepadan.
Pendekatan Migrasi: Per-Module, Bukan Big Bang #
Salah satu kesalahan terbesar dalam migrasi adalah “kita rewrite semuanya dari nol”. Saya pernah dengar cerita horor tentang tim yang spend 2 tahun untuk big-bang rewrite dan akhirnya… tidak jadi.
Pendekatan yang saya pakai:
1. Pemetaan Modul #
Pertama, map semua endpoint dan entity ke dalam modul-modul yang jelas. Dari 370+ endpoint, saya mengelompokkannya menjadi beberapa domain: authentication, tracking, reporting, user management, dan seterusnya.
2. Service–Repository Pattern #
Setiap modul di-design dengan pola service–repository:
- Repository layer — bertanggung jawab atas akses data (query ke database)
- Service layer — berisi business logic, memanggil repository
Kenapa dipisah? Karena dengan pemisahan ini:
- Repository bisa di-mock saat testing service
- Business logic bisa diuji tanpa database
- Penambahan fitur tidak merusak bagian lain
3. Satu Endpoint pada Satu Waktu #
Prosesnya kurang lebih:
- Ambil satu endpoint dari PHP
- Tulis test case berdasarkan behavior yang sudah ada
- Implementasi di Go dengan pola service–repository
- Test sampai pass
- Deploy dan monitor
- Ulangi
Ya, memang lambat. Tapi predictable. Setiap migrasi endpoint adalah incremental progress yang terukur.
Hasil yang Terukur #
Beberapa angka dari proyek ini:
- 370+ endpoint berhasil dimigrasi
- 33 entity dikonversi dari MySQL ke PostgreSQL
- 194K+ baris kode PHP ditransformasi menjadi arsitektur Go yang lebih bersih
- Response time lebih konsisten — tidak ada lagi spike yang tidak terduga
- Test coverage meningkat signifikan — dari hampir tidak ada menjadi angka yang pantas
- Developer onboarding lebih cepat — struktur kode yang jelas membuat developer baru bisa contribute lebih cepat
Yang tidak terukur tapi sangat terasa: peace of mind saat deploy. Tidak ada lagi feeling “semoga kali ini tidak ada yang break”.
Pelajaran #
Beberapa hal yang saya pelajari dari proses ini:
1. Pahami Dulu Sistem yang Ada #
Sebelum menulis satu baris pun kode Go, saya spend waktu cukup lama untuk memahami behavior sistem yang sudah ada. Bukan membaca code-nya saja — tapi memahami mengapa keputusan tertentu dibuat di masa lalu. Kadang, kode yang terlihat “aneh” punya alasan yang masuk akal di konteks saat itu dibuat.
2. Big Bang Rewrite itu Trap #
Kalau bisa sedikit-sedikit, ngapain langsung semua? Pendekatan incremental memang terasa lambat, tapi risikonya jauh lebih kecil. Setiap endpoint yang berhasil dimigrasi adalah progress yang bisa ditunjukkan ke stakeholder.
3. Test Dulu, Migrasi Kemudian #
Menulis test untuk sistem legacy itu membosankan, ya? Tapi test adalah jaring pengaman yang memastikan behavior sistem setelah migrasi tetap sama. Tanpa test, kamu tidak migrasi — kamu berjudi.
4. Jangan Prematurely Optimize #
Awalnya saya tergoda untuk langsung pakai microservices, message queue, dan arsitektur fancy lainnya. Tapi reality check: sistem yang belum stabil arsitekturnya tidak butuh microservices — butuh fondasi yang kuat. Monolith yang well-structured lebih baik daripada microservices yang chaotic.
Penutup #
Migrasi dari PHP ke Go bukan tentang “bahasa A lebih baik dari bahasa B”. Tapi tentang memilih tool yang tepat untuk masalah yang dihadapi — dan dalam kasus ini, Go dengan static typing, concurrency model, dan deployment simplicity-nya adalah pilihan yang tepat.
Kalau kamu punya sistem legacy yang mulai kepenuhan dan ingin mendiskusikan pendekatan migrasi yang tepat, hubungi saya. Atau lihat layanan yang bisa saya bantu.
Tag: go · php · arsitektur · migration