Kiến trúc tổng quan Light Stack¶
High-level Architecture¶
┌─────────────────┐
│ Client │
│ (Browser/App) │
└────────┬────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ CLOUDFLARE EDGE NETWORK │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Next.js on Workers │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ SSR │ │ API Routes │ │ Static │ │ │
│ │ │ Pages │ │ /api/* │ │ Assets │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Queue │ │ Cron │ │ KV │ │
│ │ (Messages) │ │ (Triggers) │ │ (Cache) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ SUPABASE │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ PostgreSQL │ │ Auth │ │ Storage │ │
│ │ Database │ │ (JWT) │ │ (Files) │ │
│ │ + REST │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Realtime │ │ Queue │ │ Cron │ │
│ │ (WebSocket) │ │ (pgmq) │ │ (pg_cron) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└────────────────────────────────────────────────────────────────┘
Request Flow¶
1. Static Page Request¶
Browser ──▶ Cloudflare CDN ──▶ Cached HTML
│
└── Cache HIT: Return immediately
Cache MISS: Generate from Worker
2. SSR Page Request¶
Browser ──▶ Worker ──▶ Supabase DB ──▶ Render HTML ──▶ Response
│
└── Fetch data ──▶ Build page ──▶ Cache
3. API Request¶
Browser ──▶ Worker (/api/*) ──▶ Supabase ──▶ JSON Response
│
├── Direct to Supabase REST API
└── Or custom logic in Worker
4. Background Job¶
Trigger ──▶ Queue ──▶ Worker Consumer ──▶ Process ──▶ Done
│
├── User action (enqueue)
└── Cron trigger (scheduled)
Component Responsibilities¶
Next.js (Frontend + API Gateway)¶
| Responsibility | How |
|---|---|
| UI Rendering | React components, SSR/SSG |
| Routing | App Router |
| API Gateway | Route Handlers |
| Auth middleware | Next.js Middleware |
Cloudflare (Edge Infrastructure)¶
| Responsibility | How |
|---|---|
| Hosting | Workers (compute) |
| CDN | Automatic edge caching |
| Background jobs | Queue + Cron Triggers |
| Fast storage | KV (key-value) |
Supabase (Backend Services)¶
| Responsibility | How |
|---|---|
| Database | PostgreSQL + REST API |
| Authentication | Auth service + JWT |
| File storage | Storage buckets |
| Realtime | WebSocket subscriptions |
| Background | pgmq + pg_cron |
Data Flow Patterns¶
Pattern 1: Direct Client → Supabase¶
// Client-side: Bypass Worker, direct to Supabase
const { data } = await supabase
.from('posts')
.select('*')
.eq('published', true);
Khi nào dùng: Simple reads, realtime subscriptions
Pattern 2: Client → Worker → Supabase¶
// API Route in Worker
export async function GET(request: Request) {
// Custom business logic
const data = await fetchFromSupabase();
const processed = transform(data);
return Response.json(processed);
}
Khi nào dùng: Complex logic, data transformation, auth checks
Pattern 3: Background Processing¶
// Producer: Enqueue job
await queue.send({ type: 'email', to: 'user@example.com' });
// Consumer: Process job
export default {
async queue(batch: MessageBatch) {
for (const msg of batch.messages) {
await sendEmail(msg.body);
msg.ack();
}
}
};
Khi nào dùng: Async tasks, notifications, heavy processing
Security Architecture¶
Authentication Flow¶
┌────────┐ ┌────────┐ ┌──────────┐ ┌──────────┐
│ Client │───▶│ Worker │───▶│ Supabase │───▶│ Database │
└────────┘ └────────┘ │ Auth │ └──────────┘
│ │ └──────────┘
│ │ │
│ │ ▼
│ │ ┌──────────┐
│ └───────▶│ JWT │
│ │ Validate │
│ └──────────┘
│ │
└────────────────────────────┘
Access Token
Authorization (Row Level Security)¶
-- Supabase RLS Policy
CREATE POLICY "Users can only see own data"
ON tasks FOR SELECT
USING (auth.uid() = user_id);
-- Automatic filtering based on JWT
SELECT * FROM tasks;
-- Returns only current user's tasks
Deployment Architecture¶
Environments¶
┌─────────────────────────────────────────────────────────┐
│ GitHub Repository │
└────────────────────────┬────────────────────────────────┘
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Dev │ │ Staging │ │Production│
│ Branch │ │ Branch │ │ Branch │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│Cloudflare│ │Cloudflare│ │Cloudflare│
│ Preview │ │ Staging │ │Production│
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Supabase │ │ Supabase │ │ Supabase │
│ Dev │ │ Staging │ │Production│
└──────────┘ └──────────┘ └──────────┘
Cost Breakdown by Component¶
| Component | Free Tier | Paid Tier |
|---|---|---|
| Cloudflare Workers | 100K req/day | $5/10M req |
| Cloudflare KV | 100K reads/day | $0.50/1M |
| Cloudflare Queue | 1M ops/month | $0.40/1M |
| Supabase Database | 500MB | $25/8GB |
| Supabase Auth | 50K MAU | Included |
| Supabase Storage | 1GB | $0.02/GB |
Typical PoC: $0-25/tháng
Tổng kết¶
Architecture Principles¶
- Edge-first - Compute gần user nhất
- Serverless - Không quản lý servers
- API-driven - Supabase REST API
- Event-driven - Queue cho async tasks
Key Takeaways¶
- Client có thể gọi trực tiếp Supabase (với RLS)
- Worker xử lý business logic phức tạp
- Queue cho background processing
- Cron cho scheduled tasks
Q&A¶
- Bạn thấy pattern nào phù hợp với dự án của bạn?
- Có câu hỏi gì về data flow?
- Security concerns nào bạn đang nghĩ đến?