💡 Soal 1: Analisis N+1 Query Problem & Solusinya (Eager Loading)
Definisi Masalah N+1 Query
N+1 Query Problem adalah sebuah masalah performa pada ORM (seperti Eloquent di Laravel) yang terjadi ketika aplikasi mengeksekusi satu kueri utama untuk mengambil data induk (1 kueri), lalu mengeksekusi kueri tambahan untuk setiap data anak terkait (N kueri). Jika terdapat 100 data induk, aplikasi akan menjalankan 1 + 100 = 101 kueri ke database. Hal ini menyebabkan beban kerja database membengkak dan memperlambat waktu respons aplikasi secara drastis.
Pemicu N+1 Query (Controller & Blade View)
Berikut adalah potongan kode yang memicu terjadinya N+1 Query saat mengambil data produk beserta kategorinya:
// ProductController.php (Masih Mengalami N+1)
public function index() {
// Hanya mengambil data produk tanpa merelasikan kategori dari awal
$products = Product::all();
return view('products.index', compact('products'));
}
<!-- index.blade.php -->
@foreach($products as $product)
<p>Nama Produk: {{ $product->name }}</p>
<!-- Baris di bawah ini memicu kueri baru ke tabel categories setiap kali perulangan berjalan -->
<p>Kategori: {{ $product->category->name }}</p>
@endforeach
Bukti Analisis Kueri yang Membengkak (Laravel Debugbar/Telescope)
Saat halaman diakses, tools pencatat kueri menunjukkan tumpukan kueri yang berulang untuk data yang sama:
Gambar 1.1: Daftar kueri SQL membengkak akibat N+1 Query Problem.
Solusi: Memperbaiki Kode dengan Eager Loading (with())
Untuk mengatasinya, kita menggunakan metode with() agar data relasi langsung dimuat di awal menggunakan operator IN pada SQL.
// ProductController.php (Sudah Diperbaiki)
public function index() {
// Menggunakan Eager Loading untuk memuat relasi kategori
$products = Product::with('category')->get();
return view('products.index', compact('products'));
}
Bukti Kueri Berkurang Drastis
Setelah menerapkan Eager Loading, kueri SQL terpangkas secara signifikan menjadi hanya 2 kueri saja, berapa pun jumlah datanya:
Gambar 1.2: Kueri berkurang drastis menjadi hanya 2 kueri berkat eager loading.
🔒 Soal 2: Eksperimen Keamanan Mass Assignment & White-listing
Bahaya Mass Assignment Vulnerability
Mass Assignment Vulnerability terjadi ketika sebuah framework secara buta menerima seluruh data input dari pengguna (seperti dari form atau JSON payload) dan langsung menyimpannya ke database tanpa penyaringan. Bahayanya, penyerang dapat memodifikasi parameter HTTP permintaan mereka dan menyisipkan kolom sensitif yang seharusnya tidak boleh diubah secara bebas, seperti is_admin, role, atau balance.
Simulasi Serangan Bypass via API Client (Postman/Bruno)
Penyerang mencoba mengirimkan parameter ilegal "is_admin": 1 saat melakukan registrasi akun biasa.
Gambar 2.1: Mengirimkan parameter ilegal is_admin lewat Postman.
Bukti Database Sebelum Diamankan (Serangan Berhasil)
Sebelum model dikonfigurasi dengan aman, data ilegal masuk ke database dan akun penyerang sukses menjadi Admin:
Gambar 2.2: Akun user berhasil menyusup sebagai admin pada database.
Implementasi White-listing pada Model PHP
Untuk mengamankan celah ini, kita wajib mendaftarkan properti kolom apa saja yang aman diisi oleh publik menggunakan $fillable (White-listing):
// User.php (Model)
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
// Hanya kolom di bawah ini yang diizinkan untuk diisi secara massal
protected $fillable = ['name', 'email', 'password'];
}
Pengujian Ulang dan Bukti Parameter Ilegal Diabaikan
Ketika penyerang mencoba mengirimkan payload manipulasi yang sama kembali, framework secara otomatis membuang properti yang tidak terdaftar di $fillable:
Gambar 2.3: Parameter ilegal diabaikan, user terdaftar tetap dengan hak akses biasa.
🛡️ Soal 3: Validasi Form Request & Parameter Binding Tangguh
Pentingnya Validasi di Sisi Backend (Framework) vs Frontend
Validasi frontend (HTML5/JavaScript) sangat berguna untuk memberikan pengalaman pengguna (UX) yang responsif dan cepat. Namun, validasi frontend sangat mudah dibypass. Pengguna dapat dengan mudah mematikan JavaScript di browser, memodifikasi elemen HTML via *Inspect Element*, atau mengirimkan request langsung lewat aplikasi seperti Postman. Oleh karena itu, validasi di sisi backend wajib ada karena merupakan benteng pertahanan terakhir yang menjamin integritas dan kesesuaian data sebelum masuk ke penyimpanan.
Kode Lengkap File Form Request
Berikut adalah berkas Form Request khusus untuk mengontrol aturan input pembuatan artikel:
// StoreArticleRequest.php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreArticleRequest extends FormRequest {
public function authorize(): bool {
return true; // Mengizinkan semua akses untuk simulasi ini
}
public function rules(): array {
return [
'title' => 'required|unique:articles,title|max:255',
'content' => 'required|min:20',
];
}
}
Simulasi Pelanggaran Validasi dan Tampilan Pesan Eror
Ketika diinput dengan judul yang duplikat atau isi artikel kurang dari 20 karakter, sistem secara otomatis menolak request tersebut:
Gambar 3.1: Respon otomatis sistem yang menampilkan pesan eror penolakan input data.
Mekanisme Parameter Binding Melawan SQL Injection
Saat Query Builder atau Eloquent memproses input, mereka tidak langsung menggabungkan teks input mentah ke dalam string perintah SQL. Framework menggunakan fitur Parameter Binding (memanfaatkan PDO di PHP). Input dipisahkan sebagai tempat penampung (placeholder seperti ? atau :title). Database akan mengompilasi struktur kueri SQL terlebih dahulu, baru kemudian memasukkan nilai parameternya. Akibatnya, perintah berbahaya atau karakter aneh yang disisipkan penyerang hanya akan dibaca sebagai string teks murni, bukan instruksi kode SQL baru yang tereksekusi.
💸 Soal 4: Simulasi Kegagalan Sistem Menggunakan Database Transactions
Konsep Atomisitas (All-or-Nothing)
Atomisitas (Atomicity) adalah salah satu pilar dalam prinsip ACID transaksi database. Konsep ini menyatakan bahwa sekumpulan operasi database harus dianggap sebagai satu kesatuan tunggal yang utuh (atom). Pilihannya hanya ada dua: semua perintah berhasil disimpan secara permanen (Commit), atau jika ada satu saja operasi yang gagal/eror, seluruh rangkaian perubahan dibatalkan sepenuhnya tanpa sisa (Rollback). Ini mencegah adanya ketidakkonsistenan data (seperti saldo terpotong tetapi tidak sampai ke penerima).
Potongan Kode Controller dengan Database Transaction
Berikut implementasi simulasi proses transfer saldo yang dibungkus transaksi, lengkap dengan simulasi interupsi kegagalan sistem:
// TransferController.php
use Illuminate\Support\Facades\DB;
use App\Models\Wallet;
public function transfer(Request $request) {
DB::beginTransaction(); // Memulai pembungkusan transaksi
try {
// 1. Mengurangi saldo pengirim
$sender = Wallet::find($request->sender_id);
$sender->decrement('balance', $request->amount);
// --- SIMULASI ERROR / KEGAGALAN SISTEM DI TENGAH PROSES ---
throw new \Exception('Koneksi internet terputus!');
// 2. Menambah saldo penerima (Baris ini tidak akan pernah tercapai)
$receiver = Wallet::find($request->receiver_id);
$receiver->increment('balance', $request->amount);
DB::commit(); // Eksekusi sukses semua
return response()->json(['message' => 'Transfer Berhasil!']);
} catch (\Exception $e) {
DB::rollBack(); // Membatalkan semua perubahan data jika ada eror
return response()->json(['message' => 'Transfer Gagal: ' . $e->getMessage()], 500);
}
}
Bukti Database Tetap Konsisten (Hasil Rollback)
Meskipun saldo pengirim sempat berkurang di tengah kode program, karena interupsi memicu mekanisme DB::rollBack(), kondisi tabel database kembali bersih seperti sedia kala sebelum transaksi berjalan:
Gambar 4.1: Data di database tetap utuh dan konsisten, tidak ada data sampah akibat proses yang menggantung.
🗑️ Soal 5: Implementasi Fitur Trash & Restore dengan Soft Deletes
Analisis: Kapan Menggunakan Soft Delete vs Hard Delete?
- Soft Delete: Digunakan untuk data-data penting yang bernilai tinggi bagi operasional atau riwayat bisnis user, seperti dokumen kerja, data transaksi penjualan, atau artikel blog. Tujuannya adalah untuk memberikan fitur pengamanan berupa "Kotak Sampah (Trash)", sehingga jika data tidak sengaja terhapus, pengguna masih bisa memulihkannya kembali dengan mudah.
- Hard Delete: Tepat diterapkan untuk data yang sifatnya sementara, data log aktivitas yang membengkak, data relasi usang yang sudah tidak bernilai hukum/riwayat belanja, atau ketika ada kepatuhan regulasi perlindungan privasi data (misalnya user meminta akunnya dihapus permanen demi keamanan data pribadi).
Struktur Migrasi Tabel Database (Kolom deleted_at)
Bukti bahwa skema tabel sudah mendukung Soft Deletes ditunjukkan dengan kehadiran kolom waktu penghapusan:
Gambar 5.1: Struktur tabel database yang memuat kolom deleted_at.
Implementasi Potongan Kode Kueri Framework
Berikut adalah 3 fungsi esensial untuk memanipulasi data berstatus soft-delete:
// 1. Menghapus Data Sementara (Mengisi kolom deleted_at) $article = Article::find($id); $article->delete();
// 2. Menampilkan Data yang Berada di Kotak Sampah $trashedArticles = Article::onlyTrashed()->get();
// 3. Mengembalikan Data yang Terhapus (Restore) $article = Article::withTrashed()->find($id); $article->restore();
Tampilan Antarmuka Halaman "Kotak Sampah"
Berikut adalah halaman web Kotak Sampah aplikasi yang sukses menangkap dan menampilkan baris data yang telah dihapus sementara:
Gambar 5.2: Tampilan antarmuka Kotak Sampah yang menampung file soft-deleted.
Form Komentar