Bài viết này giải thích kiến trúc một ứng dụng web hiện đại theo mô hình Frontend + Backend serverless — sử dụng Next.js cho giao diện và Firebase cho toàn bộ hạ tầng phía sau.
Dành cho ai? Bài viết dùng ngôn ngữ đời thường, không yêu cầu kiến thức lập trình. Nếu bạn đang tìm hiểu cách một ứng dụng web được xây dựng hoặc đang dùng Claude Code để tạo ứng dụng, đây là tất cả những gì bạn cần nắm.

Kiến trúc phần mềm là gì?

Kiến trúc phần mềm là bản thiết kế tổng thể mô tả cách các thành phần của ứng dụng được tổ chức và giao tiếp với nhau. Giống như bản vẽ kiến trúc nhà — bạn cần biết phòng khách ở đâu, nhà bếp nối với phòng ăn thế nào — trước khi bắt tay xây.
Phép so sánh: Kiến trúc phần mềm giống bản vẽ thiết kế nhà. Bạn không cần là thợ xây để đọc hiểu bản vẽ — nhưng hiểu bản vẽ giúp bạn ra quyết định đúng: nên đặt cửa sổ ở đâu, cần bao nhiêu phòng, đường ống nước chạy thế nào.

Tổng quan kiến trúc: 2 tầng chính

Một ứng dụng web hiện đại được chia thành 2 tầng rõ ràng:

Frontend — Giao diện

Công nghệ: Next.jsPhần người dùng nhìn thấy và tương tác: nút bấm, form nhập liệu, bảng dữ liệu, menu điều hướng, màu sắc, bố cục.

Backend & Database — Hậu trường

Công nghệ: FirebasePhần người dùng không nhìn thấy: lưu trữ dữ liệu, xác thực đăng nhập, lưu file, xử lý logic tự động.
TầngVai tròCông nghệVí dụ cụ thể
FrontendGiao diện người dùngNext.jsTrang đăng nhập, dashboard, form tạo task
BackendXử lý logic, bảo mậtFirebase (Cloud Functions, Auth)Xác thực người dùng, gửi email thông báo
DatabaseLưu trữ dữ liệuFirebase (Firestore)Danh sách tasks, thông tin users, dự án

Sơ đồ kiến trúc tổng thể

Luồng hoạt động:
  1. Người dùng mở trình duyệt, truy cập ứng dụng (ví dụ app.congty.com)
  2. Next.js hiển thị giao diện tương ứng (trang login, dashboard, danh sách task…)
  3. Khi người dùng thao tác (đăng nhập, tạo task, upload file), Firebase SDK gửi yêu cầu lên Firebase
  4. Firebase xử lý: kiểm tra quyền, lưu/đọc dữ liệu, trả kết quả về
  5. Giao diện cập nhật ngay lập tức — không cần reload trang

Tầng 1: Frontend — Next.js

Next.js đảm nhận những gì?

Next.js là framework xây dựng giao diện web, chịu trách nhiệm mọi thứ người dùng nhìn thấy và chạm vào.
Mỗi URL ứng dụng tương ứng với một trang (page). Next.js tổ chức trang theo cấu trúc thư mục — trực quan và dễ hiểu.
📁 app/
├── page.tsx            →  trang chủ "/"
├── login/page.tsx      →  trang đăng nhập "/login"
├── dashboard/
│   ├── page.tsx        →  trang tổng quan "/dashboard"
│   ├── tasks/
│   │   ├── page.tsx    →  danh sách tasks "/dashboard/tasks"
│   │   └── [id]/
│   │       └── page.tsx →  chi tiết task "/dashboard/tasks/123"
│   └── settings/
│       └── page.tsx    →  cài đặt "/dashboard/settings"
Mỗi file page.tsx = một trang web. Không cần cấu hình routing phức tạp.
Layout là phần giao diện xuất hiện trên nhiều trang mà không cần viết lại: header, sidebar, footer.
┌──────────────────────────────────────────┐
│  Header (logo, notification, avatar)     │ ← Layout gốc
├──────────┬───────────────────────────────┤
│          │                               │
│ Sidebar  │      Nội dung trang           │ ← Layout dashboard
│ (menu)   │   (thay đổi theo URL)         │
│          │                               │
└──────────┴───────────────────────────────┘
Khi chuyển trang, chỉ phần “Nội dung trang” thay đổi — header và sidebar giữ nguyên, tạo trải nghiệm mượt mà.
Component là mảnh ghép giao diện có thể tái sử dụng. Tạo một lần, dùng nhiều nơi.
📦 Components trong ứng dụng:

<TaskCard>        — Thẻ hiển thị 1 task (tiêu đề, trạng thái, deadline)
<UserAvatar>      — Ảnh đại diện người dùng
<Sidebar>         — Thanh menu bên trái
<StatusBadge>     — Badge hiển thị trạng thái (Đang làm, Hoàn thành)
<CreateTaskForm>  — Form tạo task mới
<DataTable>       — Bảng dữ liệu có sort, filter, phân trang
Cần thay đổi giao diện TaskCard? Sửa ở một chỗ duy nhất — tất cả task card trong ứng dụng cập nhật theo.
Next.js có 2 loại component, mỗi loại phù hợp với mục đích khác nhau:
LoạiChạy ở đâuDùng khi nào
Server ComponentTrên server (Vercel)Lấy dữ liệu, render HTML, bảo mật API key
Client ComponentTrong trình duyệtXử lý click, nhập liệu, cập nhật realtime
Ví dụ: Trang danh sách task dùng Server Component để lấy dữ liệu từ Firestore (nhanh, an toàn), nhưng phần nút “Thêm task” và bộ lọc trạng thái là Client Component (xử lý tương tác người dùng).

Vai trò của Next.js trong kiến trúc

Người dùng thao tác

Next.js xử lý giao diện

Firebase SDK gửi yêu cầu lên Firebase

Firebase trả dữ liệu về

Next.js cập nhật giao diện
Next.js không lưu dữ liệu. Mọi dữ liệu đều được lưu và quản lý bởi Firebase ở tầng Backend.

Tầng 2: Backend & Database — Firebase

Firebase đảm nhận những gì?

Firebase cung cấp toàn bộ hạ tầng phía sau mà ứng dụng cần — do Google vận hành, không cần tự quản lý server nào.

Firestore — Database

Lưu trữ toàn bộ dữ liệu: users, tasks, projects. Cập nhật realtime — tất cả người dùng thấy thay đổi ngay lập tức.

Authentication — Đăng nhập

Xử lý đăng ký, đăng nhập, quên mật khẩu. Hỗ trợ Google, Email, Phone OTP.

Cloud Storage — Lưu file

Lưu ảnh, video, PDF. Kiểm soát ai được xem file nào.

Cloud Functions — Logic tự động

Chạy code phía server khi có sự kiện: gửi email, tính toán, gọi API bên ngoài.

Firestore — Cơ sở dữ liệu

Firestore là nơi lưu toàn bộ dữ liệu của ứng dụng. Dữ liệu được tổ chức theo Collection → Document, tương tự thư mục chứa các file.
📁 Firestore Database
├── 👥 users/                        ← Collection "users"
│   ├── user_001/                    ← Document: 1 người dùng
│   │   ├── name: "Nguyễn Văn A"
│   │   ├── email: "a@gmail.com"
│   │   ├── role: "admin"
│   │   └── createdAt: "2026-01-15"
│   └── user_002/
│       ├── name: "Trần Thị B"
│       └── role: "member"

├── 📋 tasks/                        ← Collection "tasks"
│   ├── task_001/
│   │   ├── title: "Làm báo cáo Q1"
│   │   ├── status: "in_progress"
│   │   ├── assignee: "user_001"
│   │   ├── deadline: "2026-04-30"
│   │   └── projectId: "project_001"
│   └── task_002/
│       └── title: "Review thiết kế"

└── 🏢 projects/                     ← Collection "projects"
    └── project_001/
        ├── name: "Dự án ABC"
        ├── members: ["user_001", "user_002"]
        └── createdAt: "2026-01-01"
Tính năng đặc biệt — Realtime: Firestore cập nhật theo thời gian thực. Khi thành viên A đổi trạng thái task, màn hình thành viên B cập nhật dưới 1 giây — không cần reload.

Authentication — Xác thực người dùng

Firebase Authentication xử lý toàn bộ bài toán đăng nhập/đăng ký — bạn không cần tự xây dựng:
Phương thứcMô tả
Email & PasswordĐăng ký/đăng nhập bằng email. Firebase tự mã hóa mật khẩu, gửi email xác minh
Google Sign-InBấm “Đăng nhập với Google” → chọn tài khoản → xong
Phone OTPGửi mã SMS → nhập mã → đăng nhập (bảo mật cao)
GitHub / MicrosoftĐăng nhập bằng tài khoản nền tảng khác
Sau khi đăng nhập, Firebase cấp cho mỗi người dùng một UID (mã định danh duy nhất). Mọi dữ liệu trong Firestore đều có thể được bảo vệ theo UID:
Task của user A      → Chỉ user A thấy
Task trong project X → Chỉ thành viên project X thấy
Dữ liệu admin       → Chỉ người có role "admin" thấy

Cloud Storage — Lưu trữ file

Firestore lưu text, số, ngày tháng — nhưng không phù hợp cho file lớn. Cloud Storage giải quyết điều đó:
Loại dữ liệuVí dụ
ẢnhAvatar người dùng, ảnh đính kèm task
Tài liệuFile PDF, Word, Excel
VideoVideo bài giảng, demo sản phẩm

Cloud Functions — Logic tự động hóa

Một số tác vụ cần chạy “phía sau” — không thể để trình duyệt người dùng xử lý:
1

Trigger từ database

Khi dữ liệu trong Firestore thay đổi → tự động chạy code.Ví dụ: Task đổi sang “completed” → gửi email chúc mừng cho người thực hiện.
2

Trigger theo lịch

Chạy tự động vào thời gian đặt sẵn.Ví dụ: Mỗi sáng thứ Hai → gửi tóm tắt tuần cho team.
3

Trigger từ HTTP

Tạo API endpoint để frontend hoặc dịch vụ khác gọi.Ví dụ: Frontend gọi API thanh toán → Cloud Function xử lý với Stripe → trả kết quả.
Cloud Functions cần gói Blaze (pay-as-you-go) — nhưng có 2 triệu lượt gọi miễn phí mỗi tháng. Với ứng dụng nhỏ, chi phí gần như bằng 0.

Cách 2 tầng giao tiếp với nhau

Đây là phần quan trọng: Frontend (Next.js) và Backend (Firebase) hoạt động hoàn toàn độc lập nhưng giao tiếp qua Firebase SDK — bộ công cụ được cài trong dự án Next.js.

Luồng dữ liệu chi tiết

Ví dụ: Luồng tạo task mới (từng bước)

1

Người dùng mở form

Trên giao diện Next.js, người dùng bấm nút “Thêm task” → một Dialog (modal) hiện ra với form nhập liệu.
2

Người dùng điền thông tin

Nhập tiêu đề, mô tả, chọn người phụ trách (dropdown lấy từ Firestore collection users), chọn deadline.
3

Gửi dữ liệu lên Firebase

Bấm “Lưu” → Firebase SDK gọi addDoc() để ghi dữ liệu vào Firestore collection tasks.
4

Firestore lưu và phát sự kiện

Firestore lưu document mới và phát sự kiện realtime đến tất cả thiết bị đang mở ứng dụng.
5

Giao diện cập nhật tự động

Nhờ realtime listener, bảng danh sách tasks trên tất cả thiết bị cập nhật ngay lập tức — không cần reload.
6

Cloud Function chạy tự động (nếu có)

Nếu đã cấu hình, Cloud Function phát hiện task mới → tự động gửi email/thông báo cho người phụ trách.

Cấu trúc dự án thực tế

Khi Claude Code tạo ứng dụng theo kiến trúc này, dự án sẽ có cấu trúc thư mục:
my-app/
├── app/                              ← 🖥️ FRONTEND (Next.js)
│   ├── layout.tsx                    ← Layout gốc (Header, font, theme)
│   ├── page.tsx                      ← Trang chủ "/"
│   ├── globals.css                   ← CSS toàn cục
│   │
│   ├── (auth)/                       ← Nhóm trang xác thực
│   │   ├── login/page.tsx            ← Trang đăng nhập
│   │   └── register/page.tsx         ← Trang đăng ký
│   │
│   ├── dashboard/                    ← Khu vực sau đăng nhập
│   │   ├── layout.tsx                ← Layout có Sidebar
│   │   ├── page.tsx                  ← Trang tổng quan
│   │   ├── tasks/
│   │   │   ├── page.tsx              ← Danh sách tasks
│   │   │   └── [id]/page.tsx         ← Chi tiết từng task
│   │   └── settings/page.tsx         ← Cài đặt
│   │
│   └── api/                          ← API Routes (backend nhẹ)
│       └── send-notification/
│           └── route.ts              ← API gửi thông báo

├── components/                       ← UI Components tái sử dụng
│   ├── ui/                           ← shadcn/ui (Button, Dialog, Badge...)
│   ├── TaskCard.tsx
│   ├── Sidebar.tsx
│   └── UserAvatar.tsx

├── lib/                              ← ☁️ KẾT NỐI FIREBASE
│   ├── firebase.ts                   ← Cấu hình Firebase
│   ├── auth.ts                       ← Hàm đăng nhập/đăng ký
│   ├── firestore.ts                  ← Hàm CRUD dữ liệu
│   └── storage.ts                    ← Hàm upload/download file

├── .env.local                        ← Biến môi trường (Firebase config)
└── package.json                      ← Danh sách dependencies
Thư mục lib/cầu nối giữa Frontend và Backend. Các file trong đây chứa code gọi Firebase SDK — được import vào components và pages khi cần.

So sánh: Kiến trúc truyền thống vs kiến trúc này

Tiêu chíKiến trúc truyền thốngNext.js + Firebase
ServerTự thuê, cài đặt, bảo trìFirebase và Vercel lo toàn bộ
DatabaseTự cài MySQL/PostgreSQLFirestore (managed, realtime)
Đăng nhậpTự code auth serverFirebase Auth (sẵn sàng dùng)
DeployTự cấu hình CI/CDPush code → tự động deploy
ScaleTự cấu hình load balancerTự động scale
Chi phí ban đầu$20-100/tháng (server)$0 (gói miễn phí đủ dùng)
Thời gian setupVài ngàyVài giờ
Bảo mậtTự cập nhật, tự vá lỗiGoogle quản lý

Khi nào nên dùng kiến trúc này?

Phù hợp

  • Ứng dụng web startup, MVP
  • Ứng dụng nội bộ doanh nghiệp
  • Dashboard quản lý
  • Ứng dụng cần realtime (chat, cộng tác)
  • Task management, CRM, LMS
  • Prototype nhanh để validate ý tưởng

Cân nhắc thêm

  • Ứng dụng cần query SQL phức tạp (JOIN, GROUP BY nặng)
  • Hệ thống xử lý giao dịch tài chính quy mô lớn
  • Ứng dụng yêu cầu latency cực thấp ( dưới 10ms)
  • Hệ thống cần xử lý hàng triệu write/giây liên tục

Dùng Claude Code để xây dựng ứng dụng theo kiến trúc này

Quy trình làm việc gợi ý

1

Thiết lập dự án

Yêu cầu Claude Code khởi tạo dự án:
"Tạo dự án Next.js 15 với TypeScript, Tailwind CSS 4, shadcn/ui.
Cài Firebase SDK và tạo file cấu hình kết nối Firebase.
Firebase config: [dán firebaseConfig vào đây]"
2

Thiết kế cấu trúc dữ liệu

Mô tả dữ liệu bằng ngôn ngữ thường:
"Ứng dụng cần lưu:
- Người dùng: tên, email, phòng ban, role (admin/member)
- Công việc: tiêu đề, mô tả, trạng thái, người thực hiện, deadline
- Dự án: tên, danh sách thành viên
Thiết kế cấu trúc Firestore phù hợp."
3

Xây dựng Authentication

"Tạo trang đăng nhập tại /login.
Cho phép đăng nhập bằng Google và Email/Password.
Sau khi đăng nhập → lưu thông tin user vào Firestore → chuyển đến /dashboard."
4

Xây dựng giao diện từng trang

"Tạo trang /dashboard/tasks hiển thị danh sách công việc.
Mỗi task hiển thị: tiêu đề, badge trạng thái, người phụ trách, deadline.
Có nút 'Thêm task' mở modal form để tạo mới.
Dữ liệu lấy từ Firestore collection 'tasks', realtime."
5

Cấu hình bảo mật

"Viết Firestore Security Rules:
- User chỉ đọc/ghi dữ liệu của mình
- Task chỉ thấy bởi thành viên cùng project
- Chỉ admin mới xóa được user"
6

Deploy lên Vercel

"Hướng dẫn deploy ứng dụng lên Vercel.
Cần cấu hình biến môi trường NEXT_PUBLIC_FIREBASE_* trên Vercel."

Câu hỏi thường gặp

React thuần chỉ là thư viện UI — bạn cần tự thêm routing, SSR, API backend. Next.js xây dựng trên React và bổ sung tất cả: routing tự động, SSR/SSG, API Routes, tối ưu hình ảnh, và deploy 1 click với Vercel.Phép so sánh: React là động cơ xe, Next.js là chiếc xe hoàn chỉnh với vô lăng, ghế ngồi và điều hòa.
Firebase được dùng bởi Duolingo, Lyft, Gameloft — không chỉ dự án nhỏ. Tuy nhiên, nếu ứng dụng cần query phức tạp như SQL (JOIN nhiều bảng, GROUP BY nặng), Firestore có hạn chế hơn database SQL truyền thống. Với 90% ứng dụng web thông thường, Firestore đáp ứng được.
Giai đoạn phát triển và startup nhỏ: $0/tháng (gói Spark miễn phí đủ dùng).Có người dùng thật (vài trăm user): $5-15/tháng.Scale lớn: Trả theo mức sử dụng thực tế, có budget alerts để kiểm soát.Vercel cũng có gói miễn phí cho dự án cá nhân.
Next.js xây dựng web app — chạy tốt trên trình duyệt di động. Có thể thêm PWA để cài như app trên điện thoại.Nếu cần app native (App Store, CH Play), dùng React Native hoặc Flutter. Vì Firebase là backend chung, mobile app kết nối cùng database — không cần xây lại backend.
Frontend: Có thể chuyển từ Next.js sang framework khác (Nuxt.js, SvelteKit) vì Firebase SDK hoạt động độc lập.Backend: Chuyển từ Firebase sang backend khác (Supabase, tự build) cần effort hơn. Khi thiết kế, nên tạo tầng abstraction trong lib/ để việc migration dễ hơn — Claude Code có thể giúp làm điều này.

Tóm tắt

┌─────────────────────────────────────────────────────────────┐
│                    KIẾN TRÚC ỨNG DỤNG                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  🖥️  FRONTEND (Next.js + Vercel)                           │
│  ├── Giao diện người dùng (Pages, Layouts, Components)     │
│  ├── Routing tự động theo thư mục                          │
│  ├── Server Components (SEO, tốc độ)                       │
│  ├── Client Components (tương tác, realtime)               │
│  └── Firebase SDK (kết nối backend)                        │
│                          ↕                                  │
│  ☁️  BACKEND & DATABASE (Firebase + Google Cloud)           │
│  ├── Firestore (database NoSQL, realtime)                  │
│  ├── Authentication (đăng nhập/đăng ký)                    │
│  ├── Cloud Storage (lưu file)                              │
│  └── Cloud Functions (logic tự động)                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘
Điểm mấu chốt: Kiến trúc Next.js + Firebase cho phép bạn xây dựng ứng dụng web hoàn chỉnh mà không cần quản lý bất kỳ server nào. Frontend lo giao diện, Firebase lo toàn bộ backend — bạn chỉ cần mô tả yêu cầu cho Claude Code và tập trung vào sản phẩm.