Membuat Backend dari Aplikasi web React+Typescript

Saya memiliki sebuah aplikasi Pengajuan Dana Cash (PDC) untuk keperluan manajemen proyek di perusahaan. Aplikasi ini dibangun menggunakan antarmuka modern yang cepat dengan React, TypeScript, Vite, dan dipercantik dengan Tailwind CSS.

Namun, agar aplikasi ini bisa digunakan oleh tim secara nyata, saya harus memindahkannya ke server (cPanel) dan menghubungkannya dengan pangkalan data (database) sungguhan. Artikel ini adalah catatan perjalanan dan dokumentasi bagaimana saya mengubah aplikasi frontend statis menjadi aplikasi Full-Stack yang utuh.

Mengembangkan aplikasi React sekaligus backend PHP berarti harus sering berpindah antar file, komponen, API, dan struktur database.

Saya memilih membuat struktur folder yang benar-benar jelas agar frontend dan backend memiliki tanggung jawab masing-masing.

frontend/
backend/
database/
assets/

Pendekatan sederhana seperti ini ternyata sangat membantu ketika jumlah file mulai bertambah.

Selain itu, saya juga menyesuaikan tampilan editor kode dengan tema berwarna terang yang telah dimodifikasi agar tidak terlalu menyilaukan. Perubahan kecil tersebut ternyata cukup berpengaruh terhadap kenyamanan bekerja berjam-jam di depan monitor.

Produktivitas sering kali bukan hanya soal kemampuan menulis kode, tetapi juga bagaimana kita menciptakan lingkungan kerja yang membuat proses berpikir tetap nyaman.


Tahap 1 — Membangun Fondasi Database

Setelah frontend selesai, langkah berikutnya adalah menyiapkan "rumah" bagi seluruh data.

Saya menggunakan MySQL melalui phpMyAdmin di cPanel.

Alih-alih membuat satu tabel besar yang berisi semuanya, saya memilih pendekatan relasional.

Tabel pengajuan_dana

Berisi informasi utama dokumen seperti:

  • Nomor pengajuan
  • Tanggal
  • Departemen
  • Pemohon
  • Status pengajuan

Satu baris mewakili satu dokumen pengajuan.


Tabel pengajuan_items

Setiap dokumen tentu memiliki banyak rincian biaya.

Karena itu saya memisahkan seluruh detail pengeluaran ke tabel tersendiri.

Dengan desain ini, satu dokumen dapat memiliki puluhan bahkan ratusan item tanpa membuat struktur database menjadi berantakan.

Agar tidak terjadi konflik data, saya menggunakan Primary Key gabungan (Composite Primary Key) sehingga setiap rincian benar-benar unik.


Tabel users

Karena aplikasi nantinya digunakan oleh beberapa orang, saya juga menyiapkan tabel pengguna yang berisi:

  • Username
  • Password yang telah di-hash
  • Hak akses pengguna

Langkah ini menjadi fondasi bagi sistem autentikasi di tahap berikutnya.


Tahap 2 — Membangun Jembatan Antara React dan MySQL

Banyak pemula mengira React dapat langsung berbicara dengan MySQL.
Padahal kenyataannya tidak demikian.
React berjalan di browser, sedangkan MySQL berada di server.
Keduanya membutuhkan "penerjemah".
Di sinilah PHP Native berperan sebagai Backend API.
Saya sengaja memilih PHP murni karena:
  • ringan,
  • mudah dipindahkan ke shared hosting,
  • tidak memerlukan konfigurasi yang kompleks,
  • sangat cocok untuk aplikasi internal berskala kecil hingga menengah.

Backend yang saya bangun terdiri dari beberapa endpoint sederhana.

api_tampil.php

Mengambil data dari database, menyusunnya kembali menjadi JSON, lalu mengirimkannya ke React.

api_simpan.php

Menerima data dari formulir React kemudian menyimpannya ke MySQL.

Untuk menjaga konsistensi data, proses penyimpanan dilakukan menggunakan Database Transaction. Dengan cara ini, apabila salah satu proses gagal, seluruh transaksi akan dibatalkan sehingga tidak ada data yang tersimpan setengah jalan.

api_update_status.php

Endpoint khusus yang bertugas mengubah status pengajuan hanya dengan satu klik.

Masing-masing API memiliki tanggung jawab yang jelas sehingga proses pemeliharaan kode menjadi jauh lebih mudah.


Tahap 3 — Mengubah React Agar Berbicara dengan Server

Inilah bagian yang paling menarik.

Awalnya seluruh data diambil menggunakan:

localStorage.getItem(...)

Seluruh logika tersebut kemudian saya ubah menjadi komunikasi HTTP menggunakan fungsi fetch() bawaan JavaScript.

Alurnya menjadi seperti ini:

  1. Pengguna membuka dashboard.
  2. React mengirim permintaan ke server.
  3. PHP membaca database.
  4. MySQL mengembalikan data.
  5. PHP mengubahnya menjadi JSON.
  6. React merender seluruh data ke layar.

Begitu pula ketika pengguna menekan tombol Simpan, data langsung dikirim menuju API dan tersimpan permanen di server.

Dari sudut pandang pengguna, perubahan ini hampir tidak terlihat.

Namun dari sisi arsitektur aplikasi, perubahannya sangat besar.

Kini data dapat diakses oleh seluruh pengguna yang memiliki hak akses, bukan lagi hanya tersimpan di satu browser.


Tahap 4 — Menambahkan Lapisan Keamanan

Karena aplikasi ini berkaitan dengan pengajuan dana perusahaan, aspek keamanan menjadi prioritas utama. Saya membangun halaman login sederhana namun cukup kuat.
Alurnya adalah sebagai berikut:
  • pengguna memasukkan username dan password,
  • PHP melakukan verifikasi ke database,
  • password diperiksa menggunakan password_verify(),
  • password di database disimpan menggunakan password_hash(),
  • setelah berhasil login, server memberikan sesi autentikasi yang digunakan untuk mengakses dashboard.

Dengan pendekatan ini, password tidak pernah disimpan dalam bentuk teks biasa.

Struktur autentikasi tersebut juga cukup fleksibel apabila suatu saat ingin ditingkatkan menggunakan algoritma yang lebih modern seperti Argon2.

Selain keamanan fungsional, saya juga menggunakan identitas visual perusahaan pada halaman login agar aplikasi terlihat lebih profesional dan meningkatkan kepercayaan pengguna.


Tahap 5 — Deployment ke cPanel

Salah satu kelebihan React dengan Vite adalah proses build yang sangat sederhana.

Cukup menjalankan:

npm run build

Perintah tersebut akan:

  • mengompresi JavaScript,
  • menggabungkan aset,
  • mengoptimalkan CSS,
  • memperkecil ukuran file,
  • menghasilkan folder dist yang siap dipublikasikan.

Folder inilah yang kemudian saya unggah ke cPanel bersama seluruh file API PHP.

Dengan demikian:

  • React menangani antarmuka pengguna.
  • PHP menangani logika backend.
  • MySQL menangani penyimpanan data.

Ketiganya berjalan berdampingan di shared hosting tanpa memerlukan server Node.js yang terus aktif.

Bagi banyak developer, pendekatan seperti ini menjadi solusi yang ekonomis sekaligus praktis.


Tantangan yang Muncul di Tengah Jalan

Tidak ada proses pengembangan yang benar-benar mulus.
Beberapa masalah yang saya temui justru memberikan pelajaran yang sangat berharga.

Duplicate Entry

Awalnya database menolak penyimpanan beberapa rincian pengajuan.
Penyebabnya ternyata sederhana.
ID rincian item memiliki nilai yang sama.
Solusinya adalah mengubah desain Primary Key menjadi kombinasi antara ID Pengajuan dan ID Item sehingga setiap data memiliki identitas yang benar-benar unik.

Status "Gaib" Setelah Refresh

Pernah terjadi kondisi di mana status yang seharusnya masih Proses tiba-tiba berubah menjadi Closed ketika halaman dimuat ulang.
Setelah ditelusuri, masalahnya bukan pada database, melainkan pada perbedaan penanganan nilai antara JavaScript dan PHP.
JavaScript dapat menghasilkan nilai undefined, sedangkan PHP lebih mengenal null.
Perbedaan kecil ini ternyata cukup untuk membuat logika aplikasi menghasilkan perilaku yang tidak diharapkan.

Dashboard Tidak Sinkron

Masalah lain muncul ketika jumlah kartu statistik berbeda dengan jumlah data pada tabel.
Penyebabnya adalah logika lama masih menggunakan skema status sebelumnya.
Setelah seluruh perhitungan disesuaikan dengan struktur database terbaru, dashboard kembali konsisten.

Pelajaran yang Saya Dapatkan

Proyek ini mengajarkan satu hal yang cukup menarik.
Menulis kode hanyalah sebagian kecil dari pekerjaan seorang developer.
Yang jauh lebih penting adalah bagaimana merancang komunikasi antar komponen.
Frontend harus mampu berbicara dengan backend.
Backend harus memahami database.
Database harus mampu menjaga integritas data.
Ketika ketiga bagian tersebut dirancang dengan baik, aplikasi menjadi jauh lebih stabil, mudah dikembangkan, dan siap menghadapi kebutuhan yang lebih besar di masa depan.

Penutup

Perjalanan memindahkan aplikasi dari Local Storage menuju server sungguhan ternyata bukan sekadar proses teknis. Ini adalah proses memahami bagaimana sebuah aplikasi modern bekerja secara utuh.

Menggabungkan React, TypeScript, Vite, Tailwind CSS, PHP Native, dan MySQL memberikan keseimbangan yang menarik antara pengalaman pengguna yang cepat dengan backend yang ringan dan mudah dipelihara.

Yang paling memuaskan bukanlah ketika aplikasi berhasil diunggah ke server, melainkan ketika seluruh bagian—frontend, backend, database, autentikasi, hingga deployment—akhirnya dapat bekerja sebagai satu kesatuan yang utuh.

Jika Anda saat ini sedang membangun aplikasi React yang masih mengandalkan Local Storage, mungkin inilah saat yang tepat untuk mulai melangkah ke tahap berikutnya.

Karena di situlah proses belajar yang sesungguhnya dimulai.

Selamat bereksperimen, selamat membangun, dan semoga setiap bug yang Anda temui selalu membawa pemahaman baru.

DOKUMENTASI LAMA