Sudah berhasil vibe coding frontend tapi bingung cara atur backendnya? Artikel ini membahas cara menggunakan Supabase PostgreSQL sebagai backend untuk project vibe coding kamu. Dari pengalaman saya (Angga Risky, Founder BuildWithAngga) mengajarkan mahasiswa baru, kamu akan pelajari apa itu backend dengan analogi sederhana, 3 keunggulan Supabase yang bikin backend jadi mudah, tutorial lengkap membuat tabel untuk toko online, dan 3 kesalahan fatal yang harus dihindari. Artikel ini ditulis khusus untuk pemula yang baru pertama kali menyentuh backend, dengan penjelasan yang tidak mengasumsikan pengetahuan teknis sebelumnya.
Bagian 1: The "What Now?" Moment
Minggu lalu, saya sedang mengajar sekelompok mahasiswa baru tentang vibe coding di salah satu workshop BuildWithAngga.
Mereka excited banget. Matanya berbinar-binar.
Dalam waktu 2 jam, mereka berhasil bikin landing page toko online yang kelihatan sangat profesional. Pakai bantuan AI, tinggal tulis prompt yang jelas, generate, adjust sedikit — jadi.
Hero section dengan gambar produk? Done. Product cards yang responsive? Done. Shopping cart sidebar yang smooth? Done. Footer dengan social media links? Done.
Semua tampilan sudah perfect. Mereka bangga dengan hasilnya. Saya juga bangga dengan progress mereka.
Tapi kemudian, satu mahasiswa bernama Adi angkat tangan.
"Kak Angga, ini tombol 'Add to Cart' dipencet kok gak ngapa-ngapain? Datanya disimpen dimana sih?"
Ruangan hening sejenak.
Pertanyaan sederhana yang membuka topik besar: BACKEND.
The Gap yang Sering Terjadi
Vibe coding dengan AI memang powerful untuk bikin tampilan. HTML, CSS, bahkan JavaScript untuk animasi dan interaksi sederhana — semua bisa jadi dalam hitungan menit.
Tapi ada satu hal yang sering terlewat: Frontend tanpa backend itu seperti etalase tanpa gudang.
Coba bayangkan:
- Toko dengan display produk yang cantik, tapi tidak ada inventory system
- Form registrasi yang keren, tapi data user tidak tersimpan kemana-mana
- Shopping cart yang smooth, tapi begitu refresh halaman, semua hilang
- Tombol "Submit Order" yang satisfying diklik, tapi ordernya tidak tercatat
Itulah yang terjadi ketika tombol "Add to Cart" Adi tidak ngapa-ngapain. Frontend-nya sudah jadi, tapi tidak ada tempat untuk menyimpan data.
Kenapa Banyak Pemula Stuck di Sini?
Dari pengalaman saya mengajar ratusan mahasiswa di BuildWithAngga (BWA), ini pattern yang sering saya lihat:
JOURNEY TIPIKAL PEMULA:
Minggu 1-2: Belajar HTML & CSS
↓
"Wah, bisa bikin website!"
↓
Minggu 3-4: Belajar JavaScript
↓
"Website-ku bisa interaktif!"
↓
Minggu 5: Coba bikin project "serius"
↓
"Loh, datanya kok gak kesimpen?"
↓
STUCK 🛑
↓
"Backend itu apaan sih? Susah gak?"
↓
Overwhelmed, give up, atau cari jalan pintas
Banyak yang stuck bukan karena tidak mampu, tapi karena tidak tau harus mulai dari mana.
Ketika search "belajar backend", yang muncul:
- "Install Node.js, setup Express, connect ke MongoDB..."
- "Belajar PHP, MySQL, Apache, deployment..."
- "Django, PostgreSQL, REST API, authentication..."
Untuk pemula yang baru kenal HTML seminggu lalu, ini overwhelming.
Kabar Baiknya
Di sinilah saya biasanya bilang ke mahasiswa seperti Adi:
"Tenang. Backend di 2025 tidak sesulit yang kamu bayangkan. Ada tools yang bikin semuanya jauh lebih accessible."
Tools itu namanya Supabase.
Dan di artikel ini, saya akan share exactly apa yang saya ajarkan ke mahasiswa-mahasiswa baru BWA tentang cara "menghidupkan" hasil vibe coding mereka dengan backend yang proper.
Yang akan kamu pelajari:
| Topik | Deskripsi |
|---|---|
| Apa Itu Backend | Penjelasan dengan analogi yang mudah dipahami |
| Apa Itu Supabase | Backend-as-a-Service dengan PostgreSQL |
| 3 Keunggulan | Kenapa Supabase cocok untuk pemula |
| Tutorial Praktis | Bikin tabel products, users, orders untuk toko online |
| 3 Kesalahan Fatal | Common mistakes dan cara menghindarinya |
| Next Steps | Rekomendasi kelas fundamental di BWA |
Mari kita mulai dari pertanyaan paling basic: Apa sih sebenarnya backend itu?
Bagian 2: Apa Itu Backend? (Penjelasan dengan Analogi Sederhana)
Sebelum masuk ke Supabase dan tutorial teknis, saya selalu mulai dengan memastikan mahasiswa paham dulu konsep dasarnya.
Karena kalau tidak paham "why", nanti belajar "how" akan terasa seperti menghafal tanpa makna.
Pertanyaan yang Sering Muncul
Ketika saya tanya "Menurut kalian, backend itu apa?", jawaban yang sering muncul:
- "Yang di belakang layar, Kak?"
- "Tempat nyimpen data?"
- "Coding yang susah-susah itu?"
- "Server gitu ya?"
Semua jawaban itu benar, tapi kurang konkret untuk dipahami pemula.
Jadi saya selalu pakai analogi yang lebih relatable.
Analogi Restoran
Bayangkan kamu punya sebuah restoran.
FRONTEND = Ruang Makan
┌─────────────────────────────────────────────────────────┐
│ RUANG MAKAN │
│ (Frontend) │
├─────────────────────────────────────────────────────────┤
│ │
│ 🪑 Meja dan kursi yang nyaman │
│ 📋 Menu yang menarik dengan foto makanan │
│ 🎨 Interior yang cantik dan Instagram-worthy │
│ 👋 Pelayan yang ramah menerima pesanan │
│ 🛎️ Tombol untuk memanggil pelayan │
│ │
│ → Tempat customer MELIHAT dan BERINTERAKSI │
│ │
└─────────────────────────────────────────────────────────┘
Ruang makan adalah tempat customer datang, duduk, lihat menu, dan memesan. Semua yang customer lihat dan sentuh ada di sini.
Ini seperti HTML, CSS, dan JavaScript yang kamu buat. Tampilan website, tombol yang bisa diklik, animasi yang smooth — semua itu frontend.
BACKEND = Dapur
┌─────────────────────────────────────────────────────────┐
│ DAPUR │
│ (Backend) │
├─────────────────────────────────────────────────────────┤
│ │
│ 👨🍳 Chef yang memasak pesanan │
│ 🍳 Kompor dan peralatan masak │
│ 📝 Sistem untuk track pesanan mana yang sudah/belum │
│ ⚖️ Proses validasi (pesanan valid? bahan cukup?) │
│ 🔥 Logic bagaimana makanan diproses │
│ │
│ → Tempat pesanan DIPROSES dan DISIAPKAN │
│ → Customer TIDAK MELIHAT ini langsung │
│ │
└─────────────────────────────────────────────────────────┘
Dapur adalah tempat magic terjadi. Customer tidak lihat dapur secara langsung, tapi tanpa dapur, pesanan tidak akan pernah jadi makanan.
Ini seperti server, API, dan business logic. Tempat data diproses, validasi dilakukan, dan keputusan diambil.
DATABASE = Gudang Bahan
┌─────────────────────────────────────────────────────────┐
│ GUDANG │
│ (Database) │
├─────────────────────────────────────────────────────────┤
│ │
│ 🥬 Semua bahan makanan tersimpan rapi │
│ 📦 Tercatat: nama bahan, jumlah stok, expired date │
│ 🔍 Bisa dicari: "Ambil 2 kg daging sapi" │
│ ➕ Bisa ditambah: Supplier kirim bahan baru │
│ ➖ Bisa dikurangi: Bahan terpakai untuk masak │
│ │
│ → Tempat MENYIMPAN semua data secara terorganisir │
│ │
└─────────────────────────────────────────────────────────┘
Gudang adalah tempat semua "bahan baku" disimpan. Tanpa gudang yang terorganisir, chef tidak tau bahan apa yang tersedia, dan restoran akan chaos.
Ini seperti PostgreSQL, MySQL, atau database lainnya. Tempat data users, products, orders — semua tersimpan dengan rapi dan bisa diambil kapan saja.
Bagaimana Semuanya Bekerja Bersama
ALUR PESANAN DI RESTORAN:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ CUSTOMER │ │ DAPUR │ │ GUDANG │
│ (User/Web) │ │ (Backend) │ │ (Database) │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ 1. Lihat menu │ │
│ (Load page) │ │
│ │ │
│ 2. Pilih "Nasi │ │
│ Goreng Spesial"│ │
│ (Click button) │ │
│ │ │
│──────────────────>│ │
│ 3. Kirim pesanan │ │
│ (API request) │ │
│ │ │
│ │ 4. Check stok │
│ │────────────────────>│
│ │ (Query DB) │
│ │ │
│ │<────────────────────│
│ │ 5. "Stok ada" │
│ │ (Response) │
│ │ │
│ │ 6. Proses pesanan│
│ │ (Business │
│ │ logic) │
│ │ │
│ │ 7. Update stok │
│ │────────────────────>│
│ │ (Update DB) │
│ │ │
│<──────────────────│ │
│ 8. "Pesanan │ │
│ berhasil!" │ │
│ (Response) │ │
│ │ │
▼ ▼ ▼
Dalam konteks website toko online:
- Customer buka website → Frontend menampilkan halaman
- Customer klik "Add to Cart" → Frontend kirim request ke backend
- Backend terima request → Validasi, check stok di database
- Database merespon → "Stok tersedia" atau "Stok habis"
- Backend proses logic → Tambahkan ke cart, hitung total
- Backend kirim response → "Berhasil ditambahkan!"
- Frontend tampilkan feedback → Notifikasi hijau muncul
Tanpa Backend, Apa yang Terjadi?
Sekarang bayangkan restoran tanpa dapur dan gudang.
Customer datang, lihat menu yang cantik, pilih makanan, klik tombol "Pesan"...
Dan tidak ada yang terjadi.
Pesanan tidak tercatat. Makanan tidak dimasak. Customer menunggu selamanya.
Itulah yang terjadi ketika Adi klik tombol "Add to Cart" yang tidak ngapa-ngapain.
Frontend-nya sudah bagus. Tombolnya sudah ada. Tapi tidak ada:
- Tempat untuk menyimpan data cart
- Logic untuk memproses pesanan
- Database untuk menyimpan informasi
Tombol itu hanya hiasan — bukan tombol yang berfungsi.
Jadi, Apa Solusinya?
Untuk membuat tombol itu "hidup", kamu butuh:
- Database — Tempat menyimpan data (products, users, orders)
- API — Jembatan komunikasi antara frontend dan database
- Backend logic — Aturan bisnis (validasi, kalkulasi, dll)
Dulu, untuk setup semua ini, kamu perlu:
- Install database server (MySQL/PostgreSQL)
- Bikin backend pakai Express.js/Laravel/Django
- Setup hosting untuk server
- Konfigurasi keamanan
- Dan banyak hal teknis lainnya...
Bisa makan waktu berhari-hari sampai berminggu-minggu untuk pemula.
Tapi sekarang ada cara yang jauh lebih simple.
Namanya Supabase.
"Saya selalu bilang ke mahasiswa: Backend itu bukan monster yang harus ditakuti. Backend itu cuma 'dapur' yang perlu kamu bangun supaya 'restoran' frontend-mu bisa benar-benar berfungsi. Dan di 2025, ada tools yang bikin pembangunan dapur ini semudah menyusun LEGO."
Di bagian selanjutnya, kita akan bahas apa itu Supabase, kenapa dia cocok untuk pemula, dan 3 keunggulan utama yang bikin backend jadi tidak menakutkan lagi.
Bagian 3: Apa Itu Supabase?
Oke, sekarang kita sudah paham konsep frontend, backend, dan database dengan analogi restoran tadi.
Pertanyaan selanjutnya: Gimana cara bikin backend tanpa harus setup semuanya dari nol?
Jawabannya adalah Supabase.
Definisi Singkat
Supabase adalah Backend-as-a-Service (BaaS) yang memberikan kamu:
- Database PostgreSQL
- API otomatis
- Authentication (login/register)
- Storage (upload file)
- Real-time subscriptions
Semua dalam satu paket yang siap pakai.
Kalau pakai analogi restoran tadi: Supabase itu seperti dapur lengkap yang sudah siap pakai. Kompor ada, kulkas ada, peralatan masak ada, gudang bahan sudah terkoneksi. Kamu tinggal masak.
Tidak perlu bangun dapur dari nol. Tidak perlu beli kompor sendiri. Tidak perlu setup sistem inventory manual.
Supabase vs Bikin Backend Sendiri
| Aspek | Bikin Sendiri | Pakai Supabase |
|---|---|---|
| Setup Database | Install PostgreSQL, konfigurasi | Klik, langsung jadi |
| Bikin API | Coding Express/Laravel/Django | Otomatis ter-generate |
| Authentication | Implement sendiri dari nol | Built-in, tinggal pakai |
| Real-time | Setup WebSocket/Socket.io | Built-in |
| Hosting | Sewa server, maintain sendiri | Sudah include |
| Waktu setup | Berjam-jam sampai berhari-hari | 5-10 menit |
| Skill needed | Backend expertise | Pemula bisa |
Untuk pemula yang baru selesai vibe coding, opsi kedua jelas lebih masuk akal.
Supabase vs Firebase
Pertanyaan yang sering muncul: "Bedanya sama Firebase apa, Kak?"
Singkatnya:
- Firebase = NoSQL (document-based, seperti JSON)
- Supabase = SQL (PostgreSQL, relational tables)
Untuk aplikasi dengan relasi data yang jelas — seperti toko online dimana user punya order, order berisi products — SQL lebih natural dan mudah di-query.
Bonus: PostgreSQL adalah database yang dipakai banyak perusahaan besar. Skill yang kamu pelajari di Supabase bisa langsung transferable ke dunia kerja.
Apa yang Didapat di Free Tier?
Supabase punya free tier yang cukup generous:
SUPABASE FREE TIER:
✅ Database PostgreSQL 500 MB
✅ Auto-generated REST API
✅ Authentication (email, Google, GitHub, dll)
✅ Real-time subscriptions
✅ Storage 1 GB
✅ Edge Functions
✅ Unlimited API requests
Untuk project belajar dan MVP: lebih dari cukup.
Kamu bisa bikin project toko online, blog, aplikasi task management — semua gratis selama masih dalam limit storage.
Bagian 4: 3 Keunggulan Supabase untuk Pemula
Kenapa saya rekomendasikan Supabase ke mahasiswa yang baru belajar backend? Ada 3 alasan utama.
Keunggulan #1: PostgreSQL dengan UI Visual
PostgreSQL adalah database enterprise-grade yang dipakai perusahaan seperti Instagram, Spotify, dan Netflix.
Biasanya, untuk pakai PostgreSQL, kamu harus:
- Install di komputer
- Setup via command line
- Tulis SQL manual di terminal
- Manage connection strings
Di Supabase? Semua sudah ada UI-nya.
SUPABASE TABLE EDITOR:
┌───────────────────────────────────────────────────────────┐
│ Table: products [+] │
├───────────────────────────────────────────────────────────┤
│ id │ name │ price │ stock │ created_at │
├───────────┼─────────────┼───────────┼───────┼────────────┤
│ 1 │ Laptop │ 15000000 │ 10 │ 2025-01-15 │
│ 2 │ Mouse │ 250000 │ 50 │ 2025-01-15 │
│ 3 │ Keyboard │ 500000 │ 30 │ 2025-01-16 │
└───────────────────────────────────────────────────────────┘
Klik [+] untuk tambah row. Klik cell untuk edit.
Seperti spreadsheet, tapi ini database beneran.
Kamu bisa lihat data, tambah row, edit kolom — semua dengan klik. Tidak perlu hafal syntax SQL untuk operasi dasar.
Tentu, untuk query yang lebih kompleks tetap perlu SQL. Tapi untuk mulai? UI visual ini sangat membantu mengurangi barrier.
Keunggulan #2: Auto-Generated API
Ini yang bikin Supabase powerful untuk pemula.
Setiap tabel yang kamu buat, otomatis punya API-nya.
Bikin tabel products? API untuk GET, POST, PUT, DELETE langsung tersedia. Tidak perlu coding satu baris pun untuk backend.
Perbandingan:
TANPA SUPABASE (Manual):
├── Bikin route GET /api/products
├── Bikin route POST /api/products
├── Bikin route PUT /api/products/:id
├── Bikin route DELETE /api/products/:id
├── Handle error di setiap route
├── Validasi input
├── Connect ke database
└── Estimasi waktu: 2-4 jam untuk CRUD sederhana
DENGAN SUPABASE:
├── Bikin tabel di UI
└── API langsung ready
└── Estimasi waktu: 5 menit
Contoh cara pakai dari frontend:
// Ambil semua products
const { data, error } = await supabase
.from('products')
.select('*')
// Insert product baru
const { data, error } = await supabase
.from('products')
.insert({ name: 'Headphone', price: 500000, stock: 20 })
// Update product
const { data, error } = await supabase
.from('products')
.update({ stock: 15 })
.eq('id', 1)
// Delete product
const { data, error } = await supabase
.from('products')
.delete()
.eq('id', 1)
Simple dan readable. Tidak perlu bikin endpoint sendiri.
Keunggulan #3: Row Level Security (RLS)
Ini fitur yang sering di-skip pemula, padahal sangat penting.
RLS adalah sistem untuk mengatur siapa boleh akses data apa.
Contoh kasus:
- User A hanya boleh lihat order milik User A
- User B tidak boleh lihat order User A
- Admin boleh lihat semua order
- Guest tidak boleh lihat order sama sekali
Tanpa RLS, siapapun yang punya API key bisa akses semua data. Ini berbahaya.
TANPA RLS (Bahaya):
User random dengan API key bisa:
├── Lihat data semua user
├── Edit harga produk sesuka hati
├── Hapus order orang lain
└── Akses data sensitif
DENGAN RLS (Aman):
├── Setiap tabel punya aturan akses
├── User hanya akses data miliknya
├── Operasi sensitif butuh authentication
└── Data terproteksi by default
Di Supabase, RLS bisa di-setup dengan klik + SQL sederhana:
-- Contoh: User hanya bisa lihat order miliknya sendiri
CREATE POLICY "Users can view own orders"
ON orders FOR SELECT
USING (auth.uid() = user_id);
Sekali setup, keamanan data langsung terjaga.
Ringkasan 3 Keunggulan
┌────────────────────────────────────────────────────────────┐
│ 3 KEUNGGULAN SUPABASE UNTUK PEMULA │
├────────────────────────────────────────────────────────────┤
│ │
│ 1. PostgreSQL dengan UI Visual │
│ Database enterprise-grade, tapi mudah dipakai │
│ │
│ 2. Auto-Generated API │
│ Bikin tabel = API CRUD langsung tersedia │
│ │
│ 3. Row Level Security (RLS) │
│ Proteksi data built-in, konfigurasi mudah │
│ │
└────────────────────────────────────────────────────────────┘
Dengan 3 keunggulan ini, Supabase jadi pilihan yang solid untuk pemula yang mau belajar backend tanpa overwhelmed.
Kamu bisa fokus memahami konsep (bagaimana data mengalir, bagaimana relasi antar tabel bekerja) tanpa harus pusing dengan konfigurasi teknis di awal.
Di bagian selanjutnya, kita akan langsung praktik: daftar Supabase, buat project, dan setup tabel untuk toko online.
Bagian 5: Tutorial — Daftar Supabase dan Setup Project
Sekarang kita langsung praktik. Ikuti step-by-step di bawah ini.
Step 1: Buat Akun Supabase
- Buka supabase.com
- Klik "Start your project"
- Pilih Sign up with GitHub (recommended, lebih cepat) atau pakai email
- Authorize akses jika diminta
- Done, kamu sudah punya akun Supabase
Step 2: Buat Project Baru
Setelah login, kamu akan masuk ke dashboard.
- Klik "New Project"
- Pilih organization (biasanya nama kamu sendiri)
- Isi detail project:
| Field | Isi dengan |
|---|---|
| Project name | toko-online-belajar |
| Database password | Buat password yang kuat |
| Region | Southeast Asia (Singapore) |
- Klik "Create new project"
- Tunggu 2-3 menit sampai setup selesai
⚠️ PENTING:
Database password ini TIDAK BISA di-recover kalau lupa.
Simpan di tempat yang aman sekarang juga.
Step 3: Kenali Dashboard
Setelah project ready, kamu akan melihat dashboard seperti ini:
┌─────────────────────────────────────────────────────────┐
│ toko-online-belajar [Settings] │
├─────────────────────────────────────────────────────────┤
│ │
│ 📊 Table Editor → Bikin dan kelola tabel │
│ 🔐 Authentication → Setup login/register │
│ 📁 Storage → Upload gambar/file │
│ 🔗 API → Lihat endpoint dan docs │
│ 📈 Database → SQL Editor, Roles, dll │
│ ⚙️ Project Settings → API keys, configuration │
│ │
└─────────────────────────────────────────────────────────┘
Yang paling sering kamu pakai di awal: Table Editor dan API.
Step 4: Ambil API Keys
Untuk menghubungkan frontend ke Supabase, kamu butuh 2 hal:
- Project URL
- Anon/Public Key
Caranya:
- Klik Settings (icon gear di sidebar)
- Klik API di submenu
- Copy Project URL dan anon public key
┌─────────────────────────────────────────────────────────┐
│ API Settings │
├─────────────────────────────────────────────────────────┤
│ │
│ Project URL: │
│ <https://abcdefgh.supabase.co> [Copy] │
│ │
│ Project API Keys: │
│ │
│ anon (public): │
│ eyJhbGciOiJIUzI1NiIsInR5cCI6... [Copy] │
│ │
│ service_role (secret): │
│ eyJhbGciOiJIUzI1NiIsInR5cCI6... [Copy] │
│ ⚠️ Jangan pernah expose di frontend! │
│ │
└─────────────────────────────────────────────────────────┘
PERBEDAAN KEDUA KEY:
• anon key → Aman di frontend, dibatasi oleh RLS
• service_role → BYPASS semua security, hanya untuk server
Untuk sekarang, kamu cuma butuh anon key.
Simpan kedua nilai ini. Nanti kita pakai untuk connect dari frontend.
Bagian 6: Tutorial — Bikin Tabel untuk Toko Online
Sekarang kita bikin struktur database untuk toko online sederhana.
Planning Dulu
Sebelum bikin tabel, kita tentukan dulu apa saja yang dibutuhkan:
| Tabel | Fungsi |
|---|---|
products | Daftar produk yang dijual |
orders | Pesanan yang dibuat customer |
order_items | Detail item di setiap order |
Untuk users, Supabase sudah sediakan via Authentication. Jadi tidak perlu bikin manual.
Relasi antar tabel:
┌─────────────┐ ┌─────────────┐
│ PRODUCTS │ │ USERS │
│ │ │ (dari Auth)│
└──────┬──────┘ └──────┬──────┘
│ │
│ 1 │ 1
│ │
N N
┌──────┴──────┐ ┌──────┴──────┐
│ ORDER_ITEMS │◄────────│ ORDERS │
│ │ N │ │
└─────────────┘ └─────────────┘
Keterangan:
• 1 user bisa punya banyak orders
• 1 order bisa punya banyak order_items
• 1 product bisa ada di banyak order_items
Bikin Tabel: products
- Klik Table Editor di sidebar
- Klik "Create a new table"
- Isi nama tabel:
products - Tambahkan kolom-kolom berikut:
| Column Name | Type | Default Value | Primary |
|---|---|---|---|
id | uuid | gen_random_uuid() | ✅ |
name | text | - | |
description | text | - | |
price | int8 | - | |
stock | int4 | 0 | |
image_url | text | - | |
created_at | timestamptz | now() |
- Klik Save
💡 TIPS:
• Pakai uuid untuk id, bukan integer auto-increment
• Lebih secure karena tidak bisa ditebak urutannya
• Standard modern untuk database
Bikin Tabel: orders
Buat tabel baru dengan cara yang sama:
| Column Name | Type | Default Value | Primary |
|---|---|---|---|
id | uuid | gen_random_uuid() | ✅ |
user_id | uuid | auth.uid() | |
total_amount | int8 | 0 | |
status | text | 'pending' | |
shipping_address | text | - | |
created_at | timestamptz | now() |
💡 PENJELASAN auth.uid():
auth.uid() otomatis mengambil ID user yang sedang login.
Jadi setiap order langsung ter-link ke user yang membuatnya.
Bikin Tabel: order_items
Tabel ini menghubungkan orders dengan products:
| Column Name | Type | Default Value | Primary |
|---|---|---|---|
id | uuid | gen_random_uuid() | ✅ |
order_id | uuid | - | |
product_id | uuid | - | |
quantity | int4 | 1 | |
price_at_purchase | int8 | - |
💡 KENAPA ADA price_at_purchase?
Harga produk bisa berubah sewaktu-waktu.
Tapi harga saat customer beli harus tetap tercatat.
Contoh:
- Customer beli laptop harga 15 juta
- Minggu depan harga naik jadi 16 juta
- Order lama tetap tercatat 15 juta
Ini penting untuk akurasi laporan dan komplain customer.
Setup Foreign Keys
Setelah semua tabel dibuat, kita perlu setup relasi antar tabel.
Untuk order_items.order_id:
- Buka tabel
order_items - Klik kolom
order_id - Klik Edit Column
- Scroll ke Foreign Key Relation
- Pilih: Table
orders, Columnid - Klik Save
Untuk order_items.product_id:
Ulangi langkah yang sama, tapi pilih Table products, Column id.
Insert Sample Data
Coba masukkan beberapa data untuk testing.
- Buka tabel
products - Klik Insert Row
- Isi data:
name: Laptop Gaming ROG
description: Laptop untuk gaming dan coding
price: 15000000
stock: 10
image_url: <https://example.com/laptop.jpg>
- Klik Save
Tambahkan 2-3 produk lagi supaya ada data untuk testing.
Test API
Sekarang kita cek apakah API-nya sudah jalan.
Cara 1: Dari Dashboard
- Klik API di sidebar
- Pilih tabel
productsdi daftar - Lihat contoh request di panel kanan
- Klik "Try it out" untuk test langsung
Cara 2: Dari Terminal
curl 'https://YOUR_PROJECT_URL.supabase.co/rest/v1/products' \\
-H "apikey: YOUR_ANON_KEY" \\
-H "Authorization: Bearer YOUR_ANON_KEY"
Ganti YOUR_PROJECT_URL dan YOUR_ANON_KEY dengan nilai dari project kamu.
Expected Response:
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Laptop Gaming ROG",
"description": "Laptop untuk gaming dan coding",
"price": 15000000,
"stock": 10,
"image_url": "<https://example.com/laptop.jpg>",
"created_at": "2025-03-02T10:30:00Z"
}
]
Kalau dapat response berisi data produk, backend kamu sudah jalan.
Enable Row Level Security
Sebelum lanjut, aktifkan RLS untuk keamanan.
- Buka setiap tabel (
products,orders,order_items) - Klik tab RLS di bagian atas
- Klik Enable RLS
Untuk tabel products (public read):
-- Semua orang bisa lihat products
CREATE POLICY "Public can view products"
ON products FOR SELECT
USING (true);
Untuk tabel orders (private per user):
-- User hanya bisa lihat order miliknya
CREATE POLICY "Users can view own orders"
ON orders FOR SELECT
USING (auth.uid() = user_id);
-- User hanya bisa insert order untuk dirinya
CREATE POLICY "Users can create own orders"
ON orders FOR INSERT
WITH CHECK (auth.uid() = user_id);
Kamu bisa tambahkan policy ini via SQL Editor di sidebar.
Struktur Final
Setelah semua selesai, struktur database kamu seperti ini:
DATABASE: toko-online-belajar
├── products (RLS: public read)
│ ├── id (uuid, PK)
│ ├── name (text)
│ ├── description (text)
│ ├── price (int8)
│ ├── stock (int4)
│ ├── image_url (text)
│ └── created_at (timestamptz)
│
├── orders (RLS: user-specific)
│ ├── id (uuid, PK)
│ ├── user_id (uuid, FK → auth.users)
│ ├── total_amount (int8)
│ ├── status (text)
│ ├── shipping_address (text)
│ └── created_at (timestamptz)
│
└── order_items
├── id (uuid, PK)
├── order_id (uuid, FK → orders)
├── product_id (uuid, FK → products)
├── quantity (int4)
└── price_at_purchase (int8)
Backend untuk toko online sederhana sudah siap. Sekarang tinggal connect ke frontend.
Di bagian selanjutnya, kita akan bahas 3 kesalahan fatal yang sering dilakukan pemula saat pakai Supabase — dan cara menghindarinya.
Bagian 7: 3 Kesalahan Fatal Saat Pakai Supabase
Dari pengalaman mengajar di BuildWithAngga, ini 3 kesalahan yang paling sering saya lihat. Hindari supaya tidak buang waktu debug.
Kesalahan #1: Tidak Mengaktifkan RLS
Ini kesalahan paling berbahaya dan paling sering terjadi.
Secara default, tabel baru di Supabase bisa diakses oleh siapapun yang punya API key. Dan ingat, anon key itu public — bisa dilihat di frontend code.
Apa yang terjadi tanpa RLS:
Siapapun dengan anon key bisa:
├── SELECT * FROM users (lihat semua data user)
├── UPDATE products SET price = 0 (ubah harga jadi gratis)
├── DELETE FROM orders (hapus semua pesanan)
└── Chaos
Solusi:
- Selalu enable RLS untuk setiap tabel
- Buat policy yang sesuai kebutuhan
- Test dengan role yang berbeda
-- Minimal policy untuk tabel products
-- Public bisa baca, tapi tidak bisa edit
CREATE POLICY "Public read access"
ON products FOR SELECT
USING (true);
-- Hanya authenticated user yang bisa insert
CREATE POLICY "Authenticated users can insert"
ON products FOR INSERT
TO authenticated
WITH CHECK (true);
Jadikan ini kebiasaan: setiap bikin tabel baru, langsung setup RLS.
Kesalahan #2: Expose Service Role Key di Frontend
Supabase punya 2 jenis API key:
| Key | Sifat | Boleh di Frontend? |
|---|---|---|
anon | Public, dibatasi RLS | ✅ Ya |
service_role | Bypass semua security | ❌ Tidak |
Service role key itu seperti master key yang bisa buka semua pintu. Kalau sampai bocor ke frontend atau ke GitHub public repo, siapapun bisa:
- Akses semua data tanpa batasan
- Bypass RLS yang sudah kamu setup
- Hapus atau modifikasi apapun
Yang sering terjadi:
// ❌ SALAH - service key di frontend
const supabase = createClient(
'<https://xxx.supabase.co>',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' // service_role key
)
# ❌ SALAH - commit .env ke GitHub
SUPABASE_SERVICE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Solusi:
// ✅ BENAR - anon key di frontend
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
)
# .gitignore
.env
.env.local
.env*.local
Service role key hanya dipakai di:
- Server-side code (API routes, serverless functions)
- Script migrasi yang jalan di local
- Tidak pernah di frontend, tidak pernah di-commit
Kesalahan #3: Tidak Paham SQL Dasar
Supabase memang punya UI visual yang bagus. Tapi untuk operasi yang lebih kompleks, kamu tetap butuh SQL.
Situasi dimana pemula sering stuck:
❌ "Gimana cara JOIN data dari 2 tabel?"
❌ "Gimana filter dengan kondisi OR dan AND?"
❌ "Gimana hitung total order per user?"
❌ "Gimana bikin custom RLS policy?"
Supabase client library memang powerful:
// Ini bisa
const { data } = await supabase
.from('products')
.select('*')
.eq('stock', 0)
// Tapi ini lebih kompleks
const { data } = await supabase
.from('orders')
.select(`
*,
order_items (
quantity,
products (name, price)
)
`)
.eq('user_id', userId)
Untuk query kompleks seperti di atas, paham relasi SQL sangat membantu.
Solusi:
Pelajari SQL dasar:
SELECT,INSERT,UPDATE,DELETEWHERE,ORDER BY,LIMITJOIN(INNER, LEFT)GROUP BY,COUNT,SUM
Tidak perlu jadi expert. Paham basic sudah cukup untuk mayoritas kasus.
Di BuildWithAngga ada kelas gratis "SQL for Beginners: Learn SQL using MySQL and Database Design". Konsep SQL sama, mau pakai MySQL atau PostgreSQL.
Ringkasan 3 Kesalahan
| Kesalahan | Dampak | Solusi |
|---|---|---|
| RLS tidak aktif | Data bisa diakses siapapun | Enable RLS + buat policy |
| Service key di frontend | Bypass semua security | Hanya pakai anon key di frontend |
| Skip belajar SQL | Stuck di query kompleks | Pelajari SQL dasar |
Bagian 8: Connect Supabase ke Frontend
Sekarang kita hubungkan Supabase ke hasil vibe coding.
Install Supabase Client
Kalau project kamu pakai React, Next.js, atau framework JavaScript lainnya:
npm install @supabase/supabase-js
Setup Client
Buat file untuk inisialisasi Supabase client:
// lib/supabase.js
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseKey)
Buat file .env.local di root project:
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
Fetch Products
Ambil data produk untuk ditampilkan:
// Fungsi untuk ambil semua products
export async function getProducts() {
const { data, error } = await supabase
.from('products')
.select('*')
.order('created_at', { ascending: false })
if (error) {
console.error('Error fetching products:', error)
return []
}
return data
}
Pakai di komponen React:
// components/ProductList.jsx
import { useEffect, useState } from 'react'
import { getProducts } from '../lib/supabase'
export default function ProductList() {
const [products, setProducts] = useState([])
const [loading, setLoading] = useState(true)
useEffect(() => {
async function loadProducts() {
const data = await getProducts()
setProducts(data)
setLoading(false)
}
loadProducts()
}, [])
if (loading) return <p>Loading...</p>
return (
<div className="product-grid">
{products.map(product => (
<div key={product.id} className="product-card">
<img src={product.image_url} alt={product.name} />
<h3>{product.name}</h3>
<p>Rp {product.price.toLocaleString()}</p>
<button => addToCart(product)}>
Add to Cart
</button>
</div>
))}
</div>
)
}
Create Order
Fungsi untuk membuat pesanan:
// lib/supabase.js
export async function createOrder(items, shippingAddress) {
// Hitung total
const totalAmount = items.reduce(
(sum, item) => sum + (item.price * item.quantity),
0
)
// 1. Insert order
const { data: order, error: orderError } = await supabase
.from('orders')
.insert({
total_amount: totalAmount,
shipping_address: shippingAddress,
status: 'pending'
})
.select()
.single()
if (orderError) {
console.error('Error creating order:', orderError)
return null
}
// 2. Insert order items
const orderItems = items.map(item => ({
order_id: order.id,
product_id: item.id,
quantity: item.quantity,
price_at_purchase: item.price
}))
const { error: itemsError } = await supabase
.from('order_items')
.insert(orderItems)
if (itemsError) {
console.error('Error creating order items:', itemsError)
return null
}
return order
}
Update Stock
Kurangi stok setelah order berhasil:
export async function decreaseStock(productId, quantity) {
// Ambil stok saat ini
const { data: product } = await supabase
.from('products')
.select('stock')
.eq('id', productId)
.single()
// Update dengan stok baru
const { error } = await supabase
.from('products')
.update({ stock: product.stock - quantity })
.eq('id', productId)
if (error) {
console.error('Error updating stock:', error)
}
}
Contoh Flow Lengkap: Checkout
async function handleCheckout(cartItems, shippingAddress) {
// 1. Create order
const order = await createOrder(cartItems, shippingAddress)
if (!order) {
alert('Gagal membuat pesanan')
return
}
// 2. Update stock untuk setiap item
for (const item of cartItems) {
await decreaseStock(item.id, item.quantity)
}
// 3. Clear cart
setCart([])
// 4. Redirect ke halaman sukses
alert('Pesanan berhasil! Order ID: ' + order.id)
}
Sekarang Tombol "Add to Cart" Berfungsi
Dengan setup di atas:
- Products ditampilkan dari database ✅
- Order tersimpan ke database ✅
- Stok ter-update otomatis ✅
- Data persistent (tidak hilang saat refresh) ✅
Frontend yang tadinya "mati" sekarang sudah "hidup".
Di bagian terakhir, kita akan bahas rekomendasi langkah selanjutnya dan kelas-kelas di BuildWithAngga untuk memperdalam skill backend.
Bagian 9: Rekomendasi Kelas di BuildWithAngga
Supabase adalah titik awal yang bagus. Kamu bisa langsung lihat hasil, data tersimpan, frontend jadi hidup. Motivasi terjaga.
Tapi untuk jadi developer yang solid, kamu perlu paham apa yang terjadi di balik layar.
Supabase itu seperti mobil automatic — bagus untuk mulai dan dapat momentum. Tapi kalau mau benar-benar jago, kamu perlu paham cara kerja mesinnya.
Berikut alur belajar yang saya rekomendasikan di BuildWithAngga (BWA):
Tahap 1: Database Fundamentals
Kelas: SQL for Beginners: Learn SQL using MySQL and Database Design
📚 Yang dipelajari:
├── SELECT, INSERT, UPDATE, DELETE
├── WHERE, ORDER BY, LIMIT
├── JOIN antar tabel
├── GROUP BY dan aggregate functions
├── Database design basics
└── Best practices
💰 Harga: GRATIS
🔗 buildwithangga.com/kelas/sql-for-beginners
Ini fondasi penting. Konsep SQL sama, mau pakai MySQL, PostgreSQL, atau database lain. Setelah paham ini, query kompleks di Supabase jadi lebih mudah.
Tahap 2: JavaScript/TypeScript
Sebelum masuk framework, pastikan JavaScript-mu solid.
Kelas gratis yang tersedia:
- JavaScript Fundamentals
- React JS Fundamentals
- TypeScript basics
📚 Yang dipelajari:
├── Async/await (penting untuk API calls)
├── Array methods (map, filter, reduce)
├── ES6+ features
├── DOM manipulation
└── Error handling
Tahap 3: Full-Stack Project
Setelah fondasi kuat, saatnya bikin project lengkap.
Kelas: Full-Stack JavaScript Next JS Developer: Build Job Portal Website
📚 Yang dipelajari:
├── Next.js App Router
├── Prisma ORM + Supabase
├── Authentication dengan NextAuth
├── File upload dengan Supabase Storage
├── Full CRUD operations
└── Deployment
💰 Harga: Premium
🔗 buildwithangga.com/kelas/full-stack-javascript-next-js
Kelas ini pakai Supabase sebagai backend, jadi ilmu yang kamu dapat dari artikel ini langsung applicable.
Tahap 4: Backend Tradisional (Opsional)
Kalau mau paham backend lebih dalam, pelajari juga cara bikin backend dari nol.
Opsi yang tersedia di BWA:
| Track | Kelas |
|---|---|
| Golang | Golang Fundamental, REST API dengan Go |
| Laravel | Laravel Complete Course |
| Node.js | Express.js, NestJS |
Dengan ini, kamu paham apa yang Supabase "sembunyikan" di balik layar.
Alur Belajar Lengkap
RECOMMENDED PATH:
Minggu 1-2
└── SQL for Beginners (Gratis)
└── Paham database fundamentals
Minggu 3-4
└── JavaScript/React Fundamentals (Gratis)
└── Paham async programming
Minggu 5-8
└── Full-Stack Next.js + Supabase (Premium)
└── Bikin project lengkap
Minggu 9-12 (Opsional)
└── Backend tradisional (Golang/Laravel/Node)
└── Paham backend dari nol
OUTCOME:
├── Bisa pakai Supabase dengan baik
├── Paham SQL untuk query kompleks
├── Bisa bikin full-stack app
└── Siap untuk kerja atau freelance
Kenapa Belajar di BWA?
✅ Bahasa Indonesia — tidak ada language barrier
✅ Project-based — langsung praktik, bukan teori doang
✅ Akses seumur hidup — beli sekali, akses selamanya
✅ Forum diskusi — bisa tanya mentor kalau stuck
✅ Certificate — bukti completion untuk portfolio
✅ 200+ kelas gratis — bisa mulai tanpa bayar
Bagian 10: Penutup
Mari recap perjalanan kita di artikel ini.
Yang Sudah Dipelajari
1. THE PROBLEM
└── Vibe coding bikin frontend bagus, tapi tombol tidak berfungsi
└── Frontend tanpa backend = etalase tanpa gudang
2. KONSEP BACKEND
└── Frontend = Ruang makan (tampilan)
└── Backend = Dapur (proses)
└── Database = Gudang (penyimpanan)
3. APA ITU SUPABASE
└── Backend-as-a-Service dengan PostgreSQL
└── API otomatis, Auth built-in, RLS untuk security
4. 3 KEUNGGULAN
└── PostgreSQL dengan UI visual
└── Auto-generated API
└── Row Level Security
5. TUTORIAL PRAKTIS
└── Daftar dan setup project
└── Bikin tabel products, orders, order_items
└── Setup RLS untuk keamanan
6. 3 KESALAHAN FATAL
└── Tidak aktifkan RLS
└── Expose service key di frontend
└── Skip belajar SQL dasar
7. CONNECT KE FRONTEND
└── Install @supabase/supabase-js
└── Fetch, create, update data
└── Checkout flow lengkap
Langkah Selanjutnya
Sekarang giliran kamu:
- Buat akun Supabase — gratis, 5 menit
- Bikin project toko online — ikuti tutorial di artikel ini
- Connect ke hasil vibe coding — tombol "Add to Cart" akhirnya berfungsi
- Pelajari SQL dasar — ambil kelas gratis di BWA
- Lanjut ke full-stack — ambil kelas premium untuk project lebih kompleks
Resources
┌────────────────────────────────────────────────────────────┐
│ RESOURCES │
├────────────────────────────────────────────────────────────┤
│ │
│ 🔗 Supabase │
│ supabase.com │
│ │
│ 📚 Kelas SQL Gratis │
│ buildwithangga.com/kelas/sql-for-beginners │
│ │
│ 📚 Kelas Full-Stack Next.js + Supabase │
│ buildwithangga.com/kelas/full-stack-javascript-next-js│
│ │
│ 📚 Semua Kelas BWA │
│ buildwithangga.com/kelas │
│ │
└────────────────────────────────────────────────────────────┘
Pesan Terakhir
Backend tidak sesulit yang dibayangkan.
Dulu, untuk bikin backend, kamu perlu setup server, install database, coding API dari nol, konfigurasi keamanan — bisa makan waktu berminggu-minggu.
Sekarang? Supabase bikin semuanya bisa dilakukan dalam hitungan menit.
Tapi ingat: Supabase adalah alat bantu, bukan pengganti pemahaman. Pakai Supabase untuk dapat momentum dan melihat hasil cepat. Tapi tetap investasikan waktu untuk paham fundamentals — SQL, JavaScript, konsep backend.
Kombinasi keduanya yang akan bikin kamu jadi developer yang solid.
Artikel ini ditulis berdasarkan pengalaman mengajar mahasiswa baru di BuildWithAngga tentang transisi dari vibe coding ke full-stack development.
Semoga bermanfaat.
Angga Risky Founder, BuildWithAngga