Proxy adalah surrogate (wakil) yang mengontrol akses ke object asli. Client mengira dia pegang object asli, padahal dia pegang proxy. Proxy memutuskan: apakah call diteruskan ke asli, ditunda, di-cache, ditolak, atau dimodifikasi.
Empat varian utama:
- Virtual Proxy (lazy loading) — object asli baru dibuat saat pertama kali benar-benar dipakai. Cocok untuk object mahal (koneksi, file besar, ORM record).
- Protection Proxy — cek authorization sebelum forward call. Tidak punya hak = error.
- Cache / Remote Proxy — cache hasil, atau mewakili object yang sebenarnya ada di server lain.
- Logging / Smart Reference — track akses untuk observability atau reference counting.
Implementasi minimal — virtual proxy untuk gambar berat:
class RealImage {
constructor(filename) {
this.filename = filename;
this.loadFromDisk(); // MAHAL: baca file, decode
}
loadFromDisk() {
console.log(`Loading ${this.filename} from disk...`);
}
display() {
console.log(`Displaying ${this.filename}`);
}
}
class ImageProxy {
constructor(filename) {
this.filename = filename;
this.real = null; // belum dibuat
}
display() {
if (!this.real) this.real = new RealImage(this.filename); // baru load saat dipakai
this.real.display();
}
}
const gallery = [
new ImageProxy("cat.jpg"),
new ImageProxy("dog.jpg"),
new ImageProxy("bird.jpg"),
];
// Gallery dibuat tanpa load 3 file — cepat
gallery[0].display(); // baru load cat.jpg
// dog.jpg dan bird.jpg tidak pernah di-load kalau tidak dipakai
ES6 Proxy API — proxy built-in JavaScript:
JavaScript modern punya Proxy sebagai fitur bahasa:
const target = { name: "Ani", age: 25 };
const handler = {
get(obj, prop) {
console.log(`Akses ${prop}`);
return prop in obj ? obj[prop] : `(${prop} tidak ada)`;
},
set(obj, prop, value) {
if (prop === "age" && typeof value !== "number") {
throw new TypeError("age harus number");
}
obj[prop] = value;
return true;
},
};
const user = new Proxy(target, handler);
user.name; // "Akses name" → "Ani"
user.email; // "Akses email" → "(email tidak ada)"
user.age = 30; // OK
user.age = "dua puluh"; // TypeError!
Handler hook: get, set, has, deleteProperty, apply (kalau target function), dll. ES6 Proxy memungkinkan intercept operasi dasar bahasa, bukan cuma method.
Dunia nyata di ekosistem JS:
- Vue 3 reactivity —
refdanreactivepakai ES6 Proxy. Saat kamu akses property, Proxy track dependency; saat set, trigger re-render komponen yang pakai. Dulu Vue 2 pakaiObject.definePropertyyang lebih terbatas. - Immer — library untuk immutable update. Kamu "mutasi" draft, di balik layar Proxy track perubahan dan produce object baru tanpa ubah original.
produce(state, draft => { draft.count++ }). - MobX observable — mirip Vue, Proxy untuk reaktivitas otomatis.
- ORM lazy loading — Prisma, TypeORM sering pakai proxy untuk relasi.
user.postssebelum dipakai hanya proxy; saat diakses, query SQL dikirim. - Laravel Eloquent relation — accessor seperti
$user->postspunya logic lazy load yang secara konsep adalah proxy. - Remote proxy (RPC) —
gRPC,JSON-RPC, library seperticomlink(untuk Web Worker) bikin object remote terlihat seperti local — itu remote proxy.
Flow akses dengan caching proxy:
Kapan pakai:
- Object mahal yang belum tentu dipakai (virtual proxy)
- Akses perlu ditegakkan ijin (protection proxy)
- Perlu cache hasil antar panggilan (caching proxy)
- Butuh transparent reactive / observability (Vue, MobX, Immer)
- Object sebenarnya di remote (RPC proxy)
Kapan JANGAN pakai:
- Semua client butuh object asli penuh — proxy cuma nambah indirection
- Proxy kecil dengan logic trivial — inline saja di class asli
- Kamu overused Proxy API di tempat yang sederhana sebenarnya bisa pakai function — debuggability turun karena call tidak terlihat di stack trace
Trade-off:
Proxy powerful tapi tidak transparan untuk debugging. Stack trace di Proxy hook bisa membingungkan. Performance biasanya OK di V8 modern, tapi untuk hot path (game loop, render loop) evaluasi dulu dengan benchmark.