Web Dev 20 Sep 2026 73 views 0 komentar

Supabase untuk Pemula - Bikin Backend Web App Tanpa Coding Ribet dari Nol

Supabase untuk Pemula - Bikin Backend Web App Tanpa Coding Ribet dari Nol

Waktu itu saya lagi bikin aplikasi todo list sederhana, tapi bosen sama stack biasanya. Bikin backend Express, setup database PostgreSQL, konfigurasi auth pake JWT, bikin API CRUD... ya ribet banget rasanya. Terus saya kepikiran: "Masa siang buat bikin todo app butuh 3 hari cuma buat setup infrastruktur?" Nah, jawabannya ternyata ada Supabase.

Supabase itu open-source backend-as-a-service yang dibangun di atas PostgreSQL. Jadi bukan database baru, tapi PostgreSQL murni yang dikasih superpower: authentication, real-time subscription, auto-generated REST API, dan storage. Semuanya tinggal pakai lewat SDK JavaScript (atau Flutter, Python, dst). Kalau kamu pernah pakai Firebase, anggap aja Supabase ini versi open-source-nya tapi dengan PostgreSQL sebagai databasenya.

Apa Saja yang Supabase Tawarkan?

Supabase punya lima komponen utama yang bikin hidup developer jadi lebih mudah. Pertama, database PostgreSQL managed kamu nggak perlu install atau maintenance server database sendiri. Tinggal bikin table lewat dashboard atau SQL editor, dan database-nya langsung live. Kedua, authentication login pake email/password, Google, GitHub, magic link, semua sudah built-in. Nggak perlu bikin dari nol.

Ketiga, auto-generated API. Setiap table yang kamu bikin otomatis dapet REST endpoint dan GraphQL endpoint. Jadi frontend kamu tinggal fetch data, tanpa perlu bikin backend controller. Keempat, real-time subscription kamu bisa subscribe ke perubahan data lewat WebSocket. Kalau ada row baru di-insert, frontend langsung ke-update tanpa perlu polling. Dan kelima, storage untuk file upload (foto, dokumen, video) dengan URL signing yang aman.

Setup Project Supabase dari Nol

Pertama, kamu perlu bikin akun gratis di supabase.com. Free tier-nya lumayan generous: 500MB database, 1GB storage, 50,000 monthly active users untuk auth. Cukup buat project belajar atau bahkan production kecil. Setelah bikin project, kamu bakal dapet dua hal penting: Project URL dan anon key. Dua ini yang kamu pakai di frontend untuk connect ke Supabase.

Setelah project dibuat, masuk ke SQL Editor di dashboard. Bikin table sederhana untuk todo app kita:

-- Bikin table todos
CREATE TABLE todos (
 id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
 title TEXT NOT NULL,
 completed BOOLEAN DEFAULT FALSE,
 created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Enable Row Level Security (penting!)
ALTER TABLE todos ENABLE ROW LEVEL SECURITY;

-- Policy: siapa aja boleh baca dan insert
CREATE POLICY "Anyone can read todos" ON todos FOR SELECT USING (true);
CREATE POLICY "Anyone can insert todos" ON todos FOR INSERT WITH CHECK (true);
CREATE POLICY "Anyone can update todos" ON todos FOR UPDATE USING (true);

Perhatikan bagian Row Level Security (RLS). Ini fitur PostgreSQL yang Supabase expose dengan baik. Tanpa RLS, semua data di table kamu bisa diakses siapa aja lewat API (karena anon key kamu bakal ada di frontend). Dengan RLS, kamu bisa bikin policy: user cuma bisa baca todo miliknya sendiri, atau cuma admin yang bisa delete, atau public table yang siapa aja boleh baca.

Connect Frontend dengan Supabase JS Client

Sekarang bikin frontend-nya. Saya pakai HTML + JavaScript sederhana, tanpa framework biar gampang dipahami. Install dulu Supabase JS client:

npm install @supabase/supabase-js

Bikin file index.html dan connect ke Supabase:

<!DOCTYPE html>
<html>
<head>
 <title>Todo App dengan Supabase</title>
</head>
<body>
 <h1>My Todos</h1>
 <input type="text" id="todoInput" placeholder="Tulis todo...">
 <button onclick="addTodo()">Add</button>
 <ul id="todoList"></ul>

 <script type="module">
 import { createClient } from 'https://cdn.jsdelivr.net/npm/@supabase/supabase-js/+esm'

 const SUPABASE_URL = 'https://your-project.supabase.co'
 const SUPABASE_KEY = 'your-anon-key'

 const supabase = createClient(SUPABASE_URL, SUPABASE_KEY)

 // Load semua todo
 async function loadTodos() {
 const { data, error } = await supabase
 .from('todos')
 .select('*')
 .order('created_at', { ascending: false })

 if (error) {
 console.error('Error loading todos:', error)
 return
 }

 const list = document.getElementById('todoList')
 list.innerHTML = ''
 data.forEach(todo => {
 const li = document.createElement('li')
 li.textContent = todo.title
 li.style.textDecoration = todo.completed ? 'line-through' : 'none'
 li.onclick = () => toggleTodo(todo.id, !todo.completed)
 list.appendChild(li)
 })
 }

 // Tambah todo baru
 window.addTodo = async function() {
 const input = document.getElementById('todoInput')
 const title = input.value.trim()
 if (!title) return

 const { error } = await supabase
 .from('todos')
 .insert([{ title: title, completed: false }])

 if (error) {
 console.error('Error adding todo:', error)
 return
 }

 input.value = ''
 loadTodos()
 }

 // Toggle complete
 async function toggleTodo(id, completed) {
 const { error } = await supabase
 .from('todos')
 .update({ completed: completed })
 .eq('id', id)

 if (error) {
 console.error('Error updating todo:', error)
 return
 }

 loadTodos()
 }

 // Real-time: listen untuk perubahan
 supabase
 .channel('todos-channel')
 .on('postgres_changes',
 { event: '*', schema: 'public', table: 'todos' },
 (payload) => {
 console.log('Change received:', payload)
 loadTodos()
 }
 )
 .subscribe()

 // Load awal
 loadTodos()
 </script>
</body>
</html>

Coba perhatikan bagian real-time di atas. Saya pakai .channel() dan .on('postgres_changes', ...) untuk subscribe ke perubahan table. Setiap kali ada insert, update, atau delete dari sumber manapun (bisa dari tab browser lain, dari API client lain, atau dari SQL editor), frontend ini bakal langsung terima notifikasi dan reload data. Nggak perlu polling tiap 5 detik, nggak perlu manual refresh. Ini fitur yang biasanya butuh setup Socket.io + Redis pub/sub, di Supabase tinggal 4 baris kode.

Authentication yang Gampang Banget

Supabase auth itu salah satu alasan utama kenapa banyak developer pindah dari Firebase. Bikin login pake email/password cuma butuh beberapa baris:

// Sign up user baru
const { data, error } = await supabase.auth.signUp({
 email: '[email protected]',
 password: 'password123'
})

// Login user existing
const { data, error } = await supabase.auth.signInWithPassword({
 email: '[email protected]',
 password: 'password123'
})

// Cek user yang sedang login
const { data: { user } } = await supabase.auth.getUser()

// Logout
await supabase.auth.signOut()

Tapi yang bikin menarik adalah OAuth provider. Login pake Google atau GitHub tinggal satu baris:

// Login dengan Google
const { data, error } = await supabase.auth.signInWithOAuth({
 provider: 'google',
 options: {
 redirectTo: 'https://yourapp.com/dashboard'
 }
})

// Login dengan GitHub
const { data, error } = await supabase.auth.signInWithOAuth({
 provider: 'github'
})

Supabase juga dukung magic link (login tanpa password, link dikirim ke email) dan OTP via email atau SMS. Semua sudah built-in, kamu cuma perlu enable di dashboard. Bandingkan dengan bikin sendiri: setup SMTP, bikin template email, handle token expiry, secure storage... bisa makan berhari-hari.

Row Level Security (RLS) Keamanan di Level Database

Ini fitur yang paling sering di-skip pemula tapi paling penting. RLS bikin kamu bisa kontrol siapa boleh akses row mana, langsung di level database. Contohnya: todo app dimana user cuma boleh lihat todo miliknya sendiri.

-- Update table: tambah kolom user_id
ALTER TABLE todos ADD COLUMN user_id UUID REFERENCES auth.users(id);

-- Drop policy lama
DROP POLICY IF EXISTS "Anyone can read todos" ON todos;
DROP POLICY IF EXISTS "Anyone can insert todos" ON todos;
DROP POLICY IF EXISTS "Anyone can update todos" ON todos;

-- Policy baru: user cuma boleh akses todo miliknya
CREATE POLICY "Users can read own todos" ON todos
 FOR SELECT USING (auth.uid() = user_id);

CREATE POLICY "Users can insert own todos" ON todos
 FOR INSERT WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Users can update own todos" ON todos
 FOR UPDATE USING (auth.uid() = user_id);

-- Trigger: otomatis isi user_id saat insert
CREATE OR REPLACE FUNCTION set_user_id()
RETURNS TRIGGER AS $$
BEGIN
 NEW.user_id = auth.uid();
 RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER set_user_id_trigger
 BEFORE INSERT ON todos
 FOR EACH ROW EXECUTE FUNCTION set_user_id();

Sekarang setiap user cuma bisa baca, insert, dan update todo miliknya sendiri. User A nggak bisa lihat todo User B lewat API, meskipun keduanya pakai anon key yang sama. RLS ini dieksekusi di level PostgreSQL, jadi sangat aman. Bahkan kalau kamu bikin bug di frontend, datanya tetap nggak bocor.

Tip: saat insert dari frontend, kamu nggak perlu set user_id manual. Trigger di atas otomatis isi user_id dengan ID user yang sedang login. Supabase client otomatis kirim JWT token user, dan auth.uid() baca token itu untuk tau siapa yang login.

Storage untuk Upload File

Supabase juga punya storage bucket untuk upload file. Bikin bucket di dashboard, lalu upload dari frontend:

// Upload file ke bucket
const { data, error } = await supabase.storage
 .from('avatars')
 .upload('user-1/profile.jpg', file, {
 cacheControl: '3600',
 upsert: true
 })

// Ambil URL public
const { data } = supabase.storage
 .from('avatars')
 .getPublicUrl('user-1/profile.jpg')

// Bikin URL signed (private, expired dalam 1 jam)
const { data } = await supabase.storage
 .from('private-bucket')
 .createSignedUrl('document.pdf', 3600)

Storage ini juga dukum RLS. Kamu bisa bikin policy: user cuma boleh upload ke folder miliknya, atau cuma admin yang bisa delete file. Sangat fleksibel.

Supabase vs Firebase Mana yang Lebih Cocok?

Banyak yang tanya beda Supabase dan Firebase. Saya udah pakai keduanya, ini perbandingan jujur saya. Database: Firebase pakai NoSQL (Firestore), Supabase pakai PostgreSQL (SQL). Kalau kamu butuh relational data, join table, dan complex query, Supabase menang telak. Kalau aplikasi kamu punya struktur data yang sangat fleksibel dan sering berubah, Firestore bisa lebih gampang. Tapi jujur, 90% aplikasi web lebih cocok dengan SQL.

Real-time: Firebase punya real-time yang lebih mature, tapi Supabase juga udah stabil. Authentication: keduanya hampir sama, Firebase punya lebih banyak provider (anonymous, phone, Apple), Supabase cukup untuk mayoritas use case. Pricing: Firebase bisa expensive kalau traffic naik (baca: per-document read charges), Supabase free tier lebih generous dan pricing lebih predictable karena pakai PostgreSQL yang resource-nya fixed. Open source: Supabase bisa self-hosted kalau kamu mau, Firebase nggak.

Self-Hosting Supabase di VPS Sendiri

Salah satu keunggulan terbesar Supabase: open-source dan bisa self-host. Kalau project kamu tumbuh dan butuh kontrol penuh, kamu bisa deploy Supabase di VPS sendiri pakai Docker:

# Clone repo
git clone https://github.com/supabase/supabase
cd supabase/docker

# Copy env template
cp .env.example .env

# Edit .env: set password yang kuat
# Lalu jalankan
docker compose up -d

VPS dengan 2GB RAM udah cukup buat mulai. Saya rekomendasi pakai VPS dari provider yang lokasinya dekat dengan user kamu (Singapore kalau target Indonesia) untuk latency rendah. Setup ini butuh VPS dengan Docker terinstall, dan kamu kelola sendiri SSL pake Caddy atau nginx + Let's Encrypt.

Tips dan Pitfall yang Wajib Tau

Pertama, jangan pernah commit anon key ke public repo tanpa RLS di-enable. Anon key itu bukan rahasia emang didesain untuk di-expose di frontend. Tapi tanpa RLS, siapa aja bisa baca semua data lewat API. Kedua, hati-hati dengan free tier limits. 500MB database kelihatannya banyak, tapi kalau kamu bikin app yang store log atau upload banyak file, bisa cepat abis. Monitor usage di dashboard secara berkala.

Ketiga, pakai database function untuk logic yang kompleks. Kalau kamu butuh trigger, computed column, atau multi-step insert, bikin function di SQL level daripada di frontend. Lebih cepat dan lebih aman. Keempat, index kolom yang sering di-query. PostgreSQL otomatis index primary key, tapi kalau kamu sering query by user_id atau created_at, bikin index manual.

Kesimpulan

Supabase buat saya adalah game-changer untuk prototyping dan MVP development. Yang biasanya butuh 3-4 hari setup backend (database, auth, API, real-time), sekarang cuma butuh 30 menit bikin table + connect SDK. Untuk production, Supabase juga solid karena PostgreSQL-nya production-grade dan RLS bikin keamanan di level database.

Kalau kamu lagi cari backend untuk project pribadi atau startup kecil, coba Supabase. Free tier-nya cukup buat belajar dan bahkan launch. Dan kalau nanti butuh scale, kamu bisa upgrade ke Pro plan ($25/bulan) atau self-host di VPS sendiri. Jauh lebih murah dan fleksibel dibanding Firebase untuk skala menengah.

Pernah coba Supabase? Atau masih ragu antara Supabase vs Firebase? Cerita pengalaman kamu di komen, saya mau denger perspektif kamu juga.


Bagikan artikel ini:

Komentar (0)

Belum ada komentar. Jadilah yang pertama memberikan tanggapan!

Tinggalkan Komentar