thời gian đọc: 12 minutes

Thay vì phải lựa chọn giữa sự đơn giản của Supabase và sức mạnh của Spring Boot, tại sao không kết hợp cả hai? Hãy cùng khám phá một kiến trúc hybrid tận dụng những ưu điểm tốt nhất của mỗi công nghệ.

Table of Contents

Tiến thoái lưỡng nan giả tạo của Kiến trúc Hiện đại

Khi xây dựng một ứng dụng hiện đại với frontend tĩnh, chúng ta thường phải đối mặt với một lựa chọn nhị phân:

  • Đặt cược tất cả vào một giải pháp Backend-as-a-Service(Supabase, Firebase) - đơn giản nhưng hạn chế

  • Xây dựng một backend hoàn chỉnh(Spring Boot, Node.js) - mạnh mẽ nhưng phức tạp

Lựa chọn này là một tình thế tiến thoái lưỡng nan giả tạo. Kiến trúc hybrid đề xuất một con đường thứ ba: sử dụng mỗi công nghệ ở nơi mà nó ưu việt nhất.

Tầm nhìn Kiến trúc

Kiến trúc Truyền thống: Monolithique

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Kiến trúc truyền thống" {
  actor Utilisateur as user
  component "Frontend" as frontend #LightBlue
  component "Backend đơn thể" as backend #LightCoral {
    [Authentification]
    [CRUD]
    [Logique Métier]
    [Jobs]
    [APIs Tierces]
  }
  database "Cơ sở dữ liệu" as db #LightGray

  user --> frontend
  frontend --> backend : Tất cả các yêu cầu
  backend --> db
}

note right of backend
Tất cả đều qua backend
Dù là các thao tác đơn giản
⚠️ Điểm tắc nghẽn duy nhất
⚠️ Phức tạp ngay từ đầu
⚠️ Liên kết mật
end note
@enduml

Trong cách tiếp cận này, ngay cả những thao tác đơn giản nhất (đọc một bài viết, tạo một bình luận) cũng phải đi qua backend của bạn. Bạn phải trả giá cho sự phức tạp ngay từ ngày đầu tiên.

Kiến trúc BaaS: Ủy thác toàn bộ

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "kiến trúc BaaS thuần túy" {
  actor Utilisateur as user
  component "Giao diện trước" as frontend #LightBlue
  cloud "Supabase / Firebase" as baas #LightGreen {
    [Auth]
    [Database]
    [Storage]
    [Edge Functions]
  }

  user --> frontend
  frontend --> baas : Tất cả các hoạt động
}

note right of baas
Phát triển nhanh
Không có máy chủ để quản lý
⚠️ Giới hạn cho logic phức tạp
⚠️ Khóa nhà cung cấp
⚠️ Ràng buộc Edge Functions
end note
@enduml

Ngược lại, việc ủy thác tất cả cho một BaaS ban đầu rất hấp dẫn nhưng sẽ nhanh chóng bộc lộ những hạn chế ngay khi logic nghiệp vụ trở nên phức tạp hơn.

Kiến trúc Hybrid: Tách biệt Trách nhiệm

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

actor Utilisateur as user #LightBlue

package "Lớp Frontend" {
  component "Trang tĩnh JBake" as frontend #SkyBlue
}

package "Lớp đơn giản (Supabase)" #LightGreen {
  component "Xác thực" as auth
  component "CRUD cơ bản" as crud
  component "Lưu trữ tệp" as storage
  component "Thời gian thực" as realtime
}

package "Lớp nghiệp vụ (Spring Boot)" #Coral {
  component "Logic phức tạp" as logic
  component "Điều phối" as orchestration
  component "Công việc đã lên lịch" as jobs
  component "Tích hợp" as integrations
}

database "PostgreSQL được chia sẻ" as db #LightGray

user --> frontend

frontend --> auth : OAuth2, JWT
frontend --> crud : Bài viết, Hồ sơ
frontend --> storage : Hình ảnh, Tập tin
frontend --> realtime : Thông báo

frontend --> logic : Tính toán, Báo cáo
frontend --> orchestration : Quy trình công việc
logic --> integrations : Stripe, APIs
orchestration --> db
jobs --> db

crud --> db
auth --> db

note bottom of db
**Một nguồn chân lý duy nhất**
Chia sẻ giữa Supabase và Spring Boot
end note

note right of auth
Miễn phí tới 50k người dùng
Cấu hình chỉ trong vài cú nhấp
OAuth2 đa nhà cung cấp
end note

note right of logic
Kích hoạt chỉ khi cần thiết
Kotlin + Coroutines
Giao dịch phức tạp
end note
@enduml

Kiến trúc hybrid phân tách rõ ràng các trách nhiệm tùy theo độ phức tạp và bản chất của các thao tác.

Nguyên tắc Thiết kế

Nguyên tắc 1: Bắt đầu Đơn giản, Phát triển Thông minh

@startuml
skinparam backgroundColor #FEFEFE

rectangle "**Giai đoạn 1 : MVP**" #LightGreen {
  component "JBake + Supabase" as mvp
  note right
✓ Phát triển theo ngày
✓ Chi phí: 0€
✓ Xác thực khái niệm
  end note
}

rectangle "**Giai đoạn 2 : Tăng trưởng**" #LightYellow {
  component "JBake + Supabase\n+ Spring Boot (tuỳ chọn)" as growth
  note right
✓ Logic nghiệp vụ xuất hiện
✓ Các công việc đầu tiên được lên lịch
✓ Tích hợp bên thứ ba
  end note
}

rectangle "**Giai đoạn 3 : Quy mô**" #LightCoral {
  component "Kiến trúc hoàn chỉnh" as scale
  note right
✓ Điều phối phức tạp
✓ Hiệu suất được tối ưu
✓ Bộ nhớ cache phân tán
  end note
}

mvp -down-> growth : Khi độ phức tạp\nchứng minh điều đó
growth -down-> scale : tối ưu hóa\ntiếp tục
@enduml

Đừng xây dựng Spring Boot nếu bạn không cần đến nó.Bắt đầu với Supabase, thêm Spring Boot khi độ phức tạp đòi hỏi điều đó.

Nguyên tắc 2: Tách biệt theo Bản chất Giao dịch

@startmindmap
skinparam backgroundColor #FEFEFE
* Hoạt động\nÁp dụng

left side

** Hoạt động đơn giản\n(Supabase)
***_ CRUD Tiêu chuẩn
****_bài giảng
****_ Tạo
****Cập nhật
****_ Suppression
***_Xác thực_
****_ Đăng nhập/Logout
****_ OAuth2
****Quản lý phiên
***_ Lưu trữ
****_ Tải lên tập tin
****_ CDN tự động
***_ Thời gian thực
****_ WebSocket
****_ Thông báo

right side

** Các thao tác phức tạp\n(Spring Boot)
***logic nghiệp vụ
****_ Các tính toán phức tạp
****_ Quy tắc nghiệp vụ
****Xác thực nâng cao
***_ Điều phối
****_- đa-dịch vụ_
****_Giao dịch phân tán
****mẫu Saga
***_ Nhiệm vụ đã lên lịch
****_Báo cáo định kỳ
****_ Đồng bộ hoá
****Vệ sinh
***_ Tích hợp
****_ Thanh toán (Stripe)
****_ APIs các bên thứ ba
****_ Dịch vụ ML/AI

@endmindmap

Nguyên tắc 3: Một Nguồn Sự Thật Duy Nhất

@startuml
skinparam backgroundColor #FEFEFE

database "PostgreSQL" as db #LightGray {
  package "Schema: auth (Supabase)" #LightGreen {
    [users]
    [sessions]
    [identities]
  }

  package "Schema: public (Chia sẻ)" #SkyBlue {
    [articles]
    [comments]
    [profiles]
  }

  package "Schema: business (Spring Boot)" #Coral {
    [orders]
    [payments]
    [reports]
  }
}

component "Supabase" as supabase #LightGreen
component "Spring Boot" as spring #Coral

supabase -down-> users : Gère
supabase -down-> sessions : Gère
supabase -down-> articles : Accède
supabase -down-> comments : Accède
supabase -down-> profiles : Accède

spring -down-> articles : Accède
spring -down-> profiles : Accède
spring -down-> orders : Gère
spring -down-> payments : Gère
spring -down-> reports : Gère

note right of db
**Ưu điểm:**
• Không cần đồng bộ hóa phức tạp
• Có thể JOIN giữa các bảng
• Đảm bảo tính nhất quán
• Di chuyển dữ liệu thống nhất
end note
@enduml

Bằng cách chia sẻ cùng một instance PostgreSQL, Supabase và Spring Boot làm việc trên cùng một tập dữ liệu mà không cần đồng bộ hóa phức tạp.

Điều phối Luồng

Luồng 1: Xác thực tập trung

@startuml
skinparam backgroundColor #FEFEFE
autonumber

actor "Người dùng" as user
participant "JBake" as jbake
participant "Supabase Xác thực" as auth
participant "Spring Boot" as spring
database "PostgreSQL" as db

== Authentification ==
user -> jbake : Clique "Đăng nhập"
jbake -> auth : Chuyển hướng OAuth2 (Google/GitHub)
auth -> user : Màn hình đồng ý
user -> auth : Cho phép
auth -> auth : Tạo JWT
auth -> jbake : Trả về JWT + token làm mới
jbake -> jbake : Lưu trữ tokens (sessionStorage)

== Accès aux Ressources ==
group Opération Simple (CRUD)
  user -> jbake : Tạo một bài viết
  jbake -> db : POST với JWT
  note right: Supabase Row Level Security\nkiểm traJWT tự động
  db -> jbake : Bài viết đã được tạo
end

group Opération Complexe (Métier)
  user -> jbake : Tạo một báo cáo
  jbake -> spring : POST /api/reports\nvới JWT
  spring -> spring : Xác thực JWT Supabase
  spring -> spring : Trích xuất claims (user_id, roles)
  spring -> db : Câu truy vấn phức tạp
  spring -> jbake : Báo cáo đã được tạo
end

note over auth, spring
JWT là universal
Được xác thực bởi Supabase và Spring Boot
Không có xác thực double
end note
@enduml

Điểm mấu chốt: Một quy trình xác thực duy nhất, một JWT duy nhất, có thể sử dụng ở mọi nơi.

Flux 2 : Điều phối một Quy trình Nghiệp vụ Phức tạp

@startuml
skinparam backgroundColor #FEFEFE
autonumber

actor "Client" as user
participant "JBake" as jbake
participant "Spring Boot" as spring
participant "Supabase DB" as supadb
participant "Stripe API" as stripe
participant "Inventory Service" as inventory
participant "Email Service" as email
database "PostgreSQL" as db

user -> jbake : Đặt hàng
jbake -> spring : POST /api/orders/create

== Orchestration Spring Boot ==
spring -> db : BEGIN TRANSACTION

par Vérifications Parallèles
  spring -> inventory : Kiểm tra tồn kho
  inventory -> spring : Tồn kho OK
else
  spring -> db : Kiểm tra hồ sơ khách hàng
  db -> spring : Khách hàng đã được xác thực
end

spring -> stripe : Tạo Payment Intent
stripe -> spring : Intent đã được tạo (ID: pi_xxx)

spring -> db : Tạo Order (status: PENDING)
db -> spring : Đơn hàng đã được tạo

spring -> stripe : Xác nhận thanh toán
stripe -> spring : Thanh toán đã được xác nhận

spring -> db : Update Order (trạng thái: PAID)
spring -> inventory : Giảm tồn kho
spring -> db : COMMIT TRANSACTION

par Notifications Asynchrones
  spring -> email : Xác nhận email
else
  spring -> supadb : Chèn thông báo
  note right: Thông báo thời gian thực\nvia Supabase Realtime
end

spring -> jbake : Đơn hàng đã được xác nhận
jbake -> user : Hiển thị xác nhận

note over spring
**Nhiệm vụ Spring Boot :**
• Giao dịch ACID
• Điều phối đa dịch vụ
• Rollback tự động nếu lỗi
• Xử lý các trường hợp biên
end note
@enduml

Những gì Spring Boot mang lại: Điều phối đáng tin cậy các quy trình phức tạp liên quan đến nhiều hệ thống với đảm bảo giao dịch.

Flux 3 : Các Job Lập lịch và Đồng bộ hóa

@startuml
skinparam backgroundColor #FEFEFE

participant "Bộ lập lịch\n(Spring Boot)" as scheduler
participant "Dịch vụ báo cáo" as report
participant "PostgreSQL" as db
participant "Ngoại API" as api
participant "Dịch vụ email" as email
participant "Supabase Lưu trữ" as storage

== Job Quotidien : 2h00 ==
activate scheduler
scheduler -> report : Tạo báo cáo

activate report
report -> db : Lấy dữ liệu\ncủa 24 giờ qua
db -> report : bộ dữ liệu

report -> report : Tính toán & Tổng hợp
report -> report : Sinh ra PDF

report -> storage : Tải lên PDF
storage -> report : URL publique

report -> email : Gửi đến quản trị viên \n với liên kết PDF
deactivate report

== Job Hebdomadaire : Chủ Nhật 3:00 ==
scheduler -> report : Đồng bộ bên ngoài

activate report
report -> api : lấy dữ liệu bên ngoài
api -> report : Dữ liệu mới

report -> db : Cập nhật các bảng
report -> db : Dọn dẹp dữ liệu lỗi thời
deactivate report

== Job Mensuel : ngày đầu tiên của tháng ==
scheduler -> report : Hóa đơn

activate report
report -> db : Danh sách khách hàng hoạt động
report -> report : Tính toán các số tiền
report -> api : Tạo hóa đơn (Stripe)
report -> email : Gửi hóa đơn
deactivate report

deactivate scheduler

note right of scheduler
Không thể chỉ bằng Supabase
Edge Functions không phù hợp
cho công việc dài và lặp lại
end note
@enduml

Những gì Spring Boot mang lại: Các job lập lịch đáng tin cậy với quản lý trạng thái, tự động thử lại (retry) và đảm bảo thực thi.

Ma trận Quyết định

Khi nào nên sử dụng Supabase?

@startuml
skinparam backgroundColor #FEFEFE

start

:Nouvelle fonctionnalité à implémenter;

if (CRUD simple ?) then (oui)
  :✅ **Supabase**;
  stop
else (non)
  if (Authentification ?) then (oui)
    :✅ **Supabase Auth**;
    stop
  else (non)
    if (Upload fichiers ?) then (oui)
      :✅ **Supabase Storage**;
      stop
    else (non)
      if (Temps réel ?) then (oui)
        :✅ **Supabase Realtime**;
        stop
      else (non)
        if (Row Level Security\nsuffisante ?) then (oui)
          :✅ **Supabase + Policies**;
          stop
        else (non)
          :⚠️ **Considérer Spring Boot**;
          #Coral:Passer à l'arbre\nde décision Spring Boot;
          stop
        endif
      endif
    endif
  endif
endif

@enduml

Khi nào nên sử dụng Spring Boot?

@startuml
skinparam backgroundColor #FEFEFE

start

:Nouvelle fonctionnalité complexe;

if (Orchestration\nmulti-services ?) then (oui)
  :✅ **Spring Boot**;
  stop
else (non)
  if (Transaction ACID\ncritique ?) then (oui)
    :✅ **Spring Boot**;
    stop
  else (non)
    if (Job planifié ?) then (oui)
      :✅ **Spring Boot Scheduler**;
      stop
    else (non)
      if (Intégration API\ntierce complexe ?) then (oui)
        :✅ **Spring Boot**;
        stop
      else (non)
        if (Calculs lourds\n> 10 secondes ?) then (oui)
          :✅ **Spring Boot**;
          stop
        else (non)
          if (Cache distribué\nnécessaire ?) then (oui)
            :✅ **Spring Boot + Redis**;
            stop
          else (non)
            :⚠️ **Probablement Supabase**;
            #LightGreen:Revenir à l'arbre\nde décision Supabase;
            stop
          endif
        endif
      endif
    endif
  endif
endif

@enduml

Ví dụ về Kiến trúc theo Loại Dự án

Blog / Portfolio

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Blog Cá Nhân - 95% Supabase" {
  component "JBake" as jbake #SkyBlue

  package "Supabase (Miễn phí)" #LightGreen {
    [Auth: OAuth2 Google]
    [Articles (CRUD)]
    [Commentaires]
    [Images (Storage)]
    [Notifications Realtime]
  }

  package "Spring Boot (Tùy chọn)" #LightCoral {
    [Newsletter Mensuelle]
    note bottom: Chỉ lập lịch công việc
  }

  database "PostgreSQL" as db

  jbake --> [Auth: OAuth2 Google]
  jbake --> [Articles (CRUD)]
  jbake --> [Commentaires]
  jbake --> [Images (Storage)]
  jbake --> [Notifications Realtime]

  [Articles (CRUD)] --> db
  [Commentaires] --> db
  [Newsletter Mensuelle] --> db
}

note bottom of "Spring Boot (Tùy chọn)"
**Spring Boot không bắt buộc**
Newsletter có thể được quản lý
bởi một dịch vụ bên thứ ba (Mailchimp)
end note
@enduml

Phán quyết: 100% Supabase là quá đủ.

Ứng dụng SaaS

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Ứng dụng SaaS - Kiến trúc Hybrid" {
  component "JBake / React" as frontend #SkyBlue

  package "Supabase" #LightGreen {
    [Auth Multi-tenant]
    [Profils Utilisateurs]
    [Données Simples]
    [Storage Documents]
  }

  package "Spring Boot" #Coral {
    [Facturation (Stripe)]
    [Analytics Avancées]
    [Rapports Mensuels]
    [Quotas & Limites]
    [Webhooks Stripe]
  }

  cloud "Dịch vụ Bên ngoài" {
    [Stripe API]
    [SendGrid Email]
  }

  database "PostgreSQL Chia sẻ" as db

  frontend --> [Auth Multi-tenant]
  frontend --> [Profils Utilisateurs]
  frontend --> [Données Simples]
  frontend --> [Facturation (Stripe)]
  frontend --> [Analytics Avancées]

  [Auth Multi-tenant] --> db
  [Profils Utilisateurs] --> db
  [Données Simples] --> db

  [Facturation (Stripe)] --> db
  [Facturation (Stripe)] --> [Stripe API]
  [Analytics Avancées] --> db
  [Rapports Mensuels] --> db
  [Rapports Mensuels] --> [SendGrid Email]
  [Webhooks Stripe] ..> [Stripe API] : Écoute
}

note right of "Spring Boot"
**Cần thiết cho:**
• Quản lý gói đăng ký
• Thanh toán định kỳ
• Định mức động
• Phân tích phức tạp
• Webhook đáng tin cậy
end note
@enduml

Phán quyết: Cần kiến trúc hybrid. Supabase cho các phần cơ bản, Spring Boot cho phần quan trọng (thanh toán, lập hóa đơn).

Thương mại điện tử

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "Thương mại điện tử - 70% Spring Boot" {
  component "Storefront (JBake/React)" as frontend #SkyBlue

  package "Supabase" #LightGreen {
    [Auth Clients]
    [Catalogue Produits\n(lecture seule)]
    [Images Produits]
  }

  package "Spring Boot (Nghiệp vụ cốt lõi)" #Coral {
    [Gestion Commandes]
    [Paiements Stripe]
    [Gestion Stock]
    [Calcul Frais Port]
    [Génération Factures]
    [Synchronisation ERP]
    [Emails Transactionnels]
  }

  cloud "Tích hợp" {
    [Stripe]
    [Transporteur API]
    [ERP Externe]
  }

  database "PostgreSQL" as db

  frontend --> [Auth Clients]
  frontend --> [Catalogue Produits\n(lecture seule)]
  frontend --> [Gestion Commandes]

  [Auth Clients] --> db
  [Catalogue Produits\n(lecture seule)] --> db

  [Gestion Commandes] --> db
  [Paiements Stripe] --> [Stripe]
  [Gestion Stock] --> db
  [Calcul Frais Port] --> [Transporteur API]
  [Génération Factures] --> db
  [Synchronisation ERP] --> [ERP Externe]
  [Synchronisation ERP] --> db
}

note right of "Spring Boot (Nghiệp vụ cốt lõi)"
**Spring Boot là không thể thiếu khi:**
• Các giao dịch quan trọng
• Điều phối phức tạp
• Tích hợp đa nền tảng
• Tuân thủ pháp lý
• Các tác vụ đồng bộ hóa
end note
@enduml

Phán quyết: Spring Boot là bắt buộc. Supabase chỉ dùng cho auth và catalogue.

Chiến lược Di chuyển Tịnh tiến

@startuml
skinparam backgroundColor #FEFEFE

|Semaine 1-2|
start
:Tạo dự án Supabase;
:Cấu hình Auth (Google, GitHub);
:Định nghĩa sơ đồ PostgreSQL ban đầu;
:Thực hiện CRUD cơ bản dựa trên JBake;
:triển khai MVP trên GitHub trang;
note right
**Giao hàng :** Ứng dụng có thể hoạt động
**Chi phí :** 0€
**Thời gian :** 1-2 tuần
end note

|Semaine 3-4|
:Giám sát việc sử dụng thực tế;
:Giới hạn của identifier;

|Décision|
if (Logique complexe\némerge ?) then (non)
  |Supabase|
  :Tiếp tục với Supabase một mình;
  :Thêm Edge Functions nếu cần;
  stop
else (oui)
  |Spring Boot|
  :Tạo dự án Spring Boot;
  :Cấu hình xác thực JWT Supabase;
  :Di chuyển logic phức tạp sang Spring Boot;
  note right
Di chuyển có chọn lọc
Chỉ những thứ phức tạp
  end note
endif

|Semaines suivantes|
:Triển khai Spring Boot (Cloud Run, EC2);
:Kết nối tới PostgreSQL Supabase;
:Thực hiện các công việc lên lịch đầu tiên;
:Tích hợp APIs bên thứ ba;

stop

note right
Kiến trúc lai cuối cùng Supabase + Spring Boot trong sự hoà hợp hoàn hảo
end note
@enduml

Chi phí và Xem xét Vận hành

Cấu trúc Chi phí

@startuml
skinparam backgroundColor #FEFEFE

package "Chi phí Ước tính Hàng tháng" {

  rectangle "Giai đoạn MVP\n(0-1000 người dùng)" #LightGreen {
    [JBake (GitHub Pages): 0€]
    [Supabase: 0€]
    [Spring Boot: N/A]
    note bottom: **Tổng cộng: 0€/tháng**
  }

  rectangle "Giai đoạn Tăng trưởng\n(1k-10k người dùng)" #LightYellow {
    [JBake (GitHub Pages): 0€]
    [Supabase: 0€]
    [Spring Boot (Cloud Run): 20-50€]
    [PostgreSQL (si séparé): 0-30€]
    note bottom: **Tổng cộng: 20-80€/tháng**
  }

  rectangle "Giai đoạn Mở rộng\n(10k-100k người dùng)" #LightCoral {
    [JBake (Netlify Pro): 19€]
    [Supabase Pro: 25€]
    [Spring Boot (instances multiples): 100-300€]
    [Redis Cache: 20-50€]
    [Monitoring: 20€]
    note bottom: **Tổng cộng: 184-414€/tháng**
  }
}

note right of "Giai đoạn Mở rộng\n(10k-100k người dùng)"
Ở giai đoạn này, doanh thu hoàn toàn bù đắp được chi phí
end note
@enduml

Trách nhiệm Vận hành

@startuml
skinparam backgroundColor #FEFEFE

package "Ai Quản lý Cái gì?" {

  rectangle "Được quản lý bởi Supabase (0 công sức)" #LightGreen {
    [Authentification]
    [Base de données]
    [Backups automatiques]
    [Scaling automatique]
    [Monitoring DB]
    [Sécurité DB]
  }

  rectangle "Được quản lý bởi GitHub (0 công sức)" #SkyBlue {
    [Hébergement site statique]
    [HTTPS/SSL]
    [CDN global]
    [Déploiement automatique]
  }

  rectangle "Cần Quản lý (Spring Boot)" #LightCoral {
    [Déploiement application]
    [Monitoring APM]
    [Logs centralisés]
    [Scaling horizontal]
    [Mises à jour sécurité]
  }
}

note bottom of "Cần Quản lý (Spring Boot)"
**Có thể tối thiểu hóa với:**
• Cloud Run (serverless)
• Kubernetes (nếu cần thiết)
• Các dịch vụ quản lý (RDS, v.v.)
end note
@enduml

Kết luận: Sự Cân Bằng Hoàn Hảo

Kiến trúc hybrid Supabase + Spring Boot không phải là một sự thỏa hiệp, mà là mộtsự hiệp lựcVui lòng cung cấp văn bản tiếng Pháp cần dịch.

Các Nguyên Tắc Cần Ghi Nhớ

@startmindmap
skinparam backgroundColor #FEFEFE
* Kiến trúc\nLai ghép

** Bắt đầu đơn giản
***_ MVP với Supabase
***_ 0€ chi phí ban đầu
***Xác thực nhanh

** Phát triển một cách thông minh
***_ Thêm Spring Boot\ncần thiết
***_ Di động dần
***_ Không có việc thiết kế lại hoàn toàn

** Tận dụng các sức mạnh
***_ Supabase: Đơn giản
***_ Spring Boot: Sức mạnh
***_ PostgreSQL: Nguồn duy nhất

** Giảm độ phức tạp
***_ Không đồng bộ
***_ Không được trùng lặp
***_ Kiến trúc rõ ràng

** Tối ưu hoá chi phí
***_ Miễn phí khi bắt đầu
***'_ Mở rộng từng bước'
***_ ROI rõ ràng

@endmindmap

Khi Nào Nên Chọn Kiến Trúc Này?

✅ Kiến trúc này là lý tưởng nếu:

  • Bạn muốn khởi động nhanh chóng (MVP tính bằng ngày, không phải bằng tháng)

  • Bạn dự báo sự gia tăng về độ phức tạp của nghiệp vụ

  • Bạn muốn giảm thiểu chi phí ban đầu

  • Bạn yêu thích PostgreSQL và muốn có một nguồn sự thật duy nhất

  • Bạn yêu thích Kotlin và Coroutines cho mã nguồn nghiệp vụ

  • Bạn muốn tránh tình trạng bị vendor lock-in hoàn toàn

❌ Kiến trúc này KHÔNG phù hợp nếu:

  • Dự án của bạn đơn giản và sẽ tiếp tục như vậy (blog cá nhân → 100% Supabase là đủ)

  • Bạn đã có một stack backend thiết lập sẵn mà bạn thành thạo

  • Bạn thích một khối đơn khối truyền thống hơn

  • Bạn cần .NET, Python, hoặc ngôn ngữ khác ở phía backend

Tổng quan Cuối cùng

@startuml
skinparam backgroundColor #FEFEFE

package "Kiến trúc Hybrid Toàn diện" {

  actor "Người dùng" as users

  rectangle "Frontend (Tĩnh)" #SkyBlue {
    [JBake / GitHub Pages]
    note right: Miễn phí, CDN toàn cầu
  }

  rectangle "Backend Đơn giản (Supabase)" #LightGreen {
    [Auth OAuth2]
    [CRUD APIs]
    [Storage]
    [Realtime]
    note right
Miễn phí lên đến 50k users
Không cần cấu hình máy chủ
    end note
  }

  rectangle "Backend Nghiệp vụ (Spring Boot)" #Coral {
    [Orchestration]
    [Jobs Planifiés]
    [Intégrations]
    [Transactions]
    note right
Chỉ kích hoạt
nếu cần thiết
    end note
  }

  database "PostgreSQL\nNguồn Sự thật Duy nhất" as db #LightGray

  users --> [JBake / GitHub Pages]

  [JBake / GitHub Pages] --> [Auth OAuth2]
  [JBake / GitHub Pages] --> [CRUD APIs]
  [JBake / GitHub Pages] --> [Storage]
  [JBake / GitHub Pages] --> [Realtime]
  [JBake / GitHub Pages] --> [Orchestration]

  [Auth OAuth2] --> db
  [CRUD APIs] --> db
  [Orchestration] --> db
  [Jobs Planifiés] --> db
  [Intégrations] --> db
}

note bottom of db
**Một cơ sở dữ liệu, hai người tiêu dùng**
• Supabase cho những thứ đơn giản
• Spring Boot cho những thứ phức tạp
• Không yêu cầu đồng bộ hóa
end note

@enduml

Điều Tốt Nhất Của Cả Hai Thế Giới

Kiến trúc này cung cấp cho bạn:

🚀 Tốc độ của Supabase

  • Khởi động trong vài giờ, không phải vài tuần

  • Xác thực OAuth2 chỉ với vài cú nhấp chuột

  • Các API REST được tạo tự động

  • Không cần cấu hình máy chủ

💪 Sức mạnh của Spring Boot

  • Kotlin và Coroutines cho mã bất đồng bộ thanh thoát

  • Điều phối các quy trình kinh doanh phức tạp

  • Các tác vụ lập lịch đáng tin cậy

  • Đảm bảo giao dịch ACID

  • Hệ sinh thái Spring toàn diện

💰 Nền Kinh tế Tiến bộ

  • 0€ để bắt đầu và xác nhận

  • Chi phí tăng theo tăng trưởng

  • Không thiết kế quá mức sớm (no premature over-engineering)

🎯 Tính Linh hoạt của Kiến trúc

  • Di cư dần dần không cần tái thiết kế

  • Thêm Spring Boot chỉ khi cần thiết

  • Không bị khóa chặt hoàn toàn vào nhà cung cấp (vendor lock-in)

  • Kiến trúc có khả năng mở rộng

Tìm hiểu thêm

Tài nguyên Kỹ thuật

Tài liệu Supabase:

Tài liệu Spring Boot :

Bài viết Bổ sung:

  • Bảo mật API với JWT

  • Tối ưu hóa hiệu suất PostgreSQL

  • Các mẫu di cư lũy tiến

  • Quản lý lỗi trong kiến trúc phân tán

Các Trường Hợp Sử Dụng Thực Tế

Kiến trúc hybrid này được sử dụng thành công trong:

  • SaaS B2B: Xác thực Supabase, thanh toán Spring Boot

  • Sàn thương mại điện tử: Danh mục Supabase, giao dịch Spring Boot

  • Nền tảng nội dung: Các bài viết về Supabase, analytics Spring Boot

  • Công cụ nội bộ: CRUD Supabase, workflows Spring Boot

Danh sách kiểm tra khởi động

Giai đoạn 1 - Nền móng (Tuần 1)

  • Tạo tài khoản Supabase - [ ] Cấu hình dự án PostgreSQL - [ ] Kích hoạt Auth (Google, GitHub) - [ ] Định nghĩa sơ đồ ban đầu - [ ] Cấu hình Row Level Security - [ ] Kiểm tra các API từ JBake

Giai đoạn 2 - MVP (Tuần 2-3)

  • Triển khai các trang chính - [ ] Tích hợp xác thực OAuth2 - [ ] Tạo các biểu mẫu CRUD - [ ] Cấu hình Storage cho các tệp tin - [ ] Triển khai lên GitHub Pages - [ ] Kiểm tra trong điều kiện thực tế

Giai đoạn 3 - Phát triển (Theo nhu cầu)

  • Xác định các nhu cầu về logic phức tạp - [ ] Tạo dự án Spring Boot nếu cần thiết - [ ] Cấu hình xác thực JWT Supabase - [ ] Kết nối với PostgreSQL Supabase - [ ] Di chuyển các tính năng phức tạp - [ ] Triển khai các job lập lịch - [ ] Triển khai Spring Boot (Cloud Run, v.v.)

Các Anti-Pattern cần tránh

❌ Không được làm:

  • Sao chép dữ liệu giữa Supabase và Spring Boot

  • Tạo hai cơ sở dữ liệu PostgreSQL riêng biệt

  • Tự viết mã xác thực

  • Sử dụng Spring Boot cho CRUD đơn giản

  • Thiết kế quá mức ngay từ đầu

  • Bỏ qua Row Level Security của Supabase

✅ Thay vào đó hãy làm:

  • Chia sẻ một cơ sở dữ liệu PostgreSQL duy nhất

  • Để Supabase quản lý xác thực

  • Chỉ sử dụng Spring Boot cho những phần phức tạp

  • Bắt đầu đơn giản, phát triển dần dần

  • Khai thác thế mạnh của mỗi công nghệ

  • Bảo mật với RLS ở cấp độ cơ sở dữ liệu

Triển vọng Phát triển

Thêm các Khả năng Mới

@startuml
skinparam backgroundColor #FEFEFE

rectangle "Kiến trúc Hiện tại" #SkyBlue {
  [JBake]
  [Supabase]
  [Spring Boot]
}

rectangle "Các hướng Phát triển Có thể" #LightYellow {

  package "Hiệu năng" {
    [Redis Cache]
    [CDN pour Assets]
    [PostgreSQL Replicas]
  }

  package "Giám sát" {
    [Grafana]
    [Prometheus]
    [Sentry]
  }

  package "CI/CD" {
    [GitHub Actions]
    [Tests Automatisés]
    [Déploiement Continu]
  }

  package "Tính năng" {
    [Search (ElasticSearch)]
    [Queue (RabbitMQ)]
    [Event Sourcing]
  }
}

[Spring Boot] .down.> [Redis Cache] : Peut ajouter
[Spring Boot] .down.> [Queue (RabbitMQ)] : Peut ajouter
[Spring Boot] .down.> [Search (ElasticSearch)] : Peut ajouter

[Supabase] .down.> [PostgreSQL Replicas] : Peut ajouter

note bottom
**Kiến trúc có thể mở rộng**
Mỗi phần bổ sung là độc lập
Không cần thiết phải tái thiết kế toàn bộ
end note
@enduml

Mở rộng theo chiều ngang

Khi ứng dụng của bạn phát triển, kiến trúc hybrid sẽ mở rộng một cách tự nhiên:

Supabase :

  • Tự động mở rộng quy mô lên đến hàng triệu thao tác

  • Read replicas để tăng hiệu suất đọc

  • Phục hồi tại một thời điểm (Point-in-time recovery) để bảo mật

Spring Boot :

  • Nhiều instance phía sau load balancer

  • Thiết kế Stateless tạo điều kiện cho việc scaling horizontal

  • Kubernetes để điều phối nếu cần thiết

PostgreSQL :

  • Phân vùng cho các bảng có dung lượng lớn

  • Nhóm kết nối (PgBouncer)

  • Sharding nếu thực sự cần thiết (hiếm)

Minh chứng Kiến trúc

Startup SaaS (50k người dùng)

Vui lòng cung cấp văn bản cần dịch. Chúng tôi đã khởi đầu với 100% Supabase. Khi đạt 5k người dùng, chúng tôi đã thêm Spring Boot chỉ để phục vụ việc lập hóa đơn Stripe và các báo cáo hàng tháng. Một năm sau, 80% các hoạt động của chúng tôi vẫn thông qua Supabase. Spring Boot chỉ quản lý phần quan trọng. Sự phân tách này đã cho phép chúng tôi mở rộng quy mô mà không cần tái cấu trúc. Vui lòng cung cấp văn bản cần dịch.

Nền tảng E-learning (10k người dùng)

Vui lòng cung cấp văn bản cần dịch. Xác thực OAuth2 của Supabase đã giúp chúng tôi tiết kiệm được 3 tuần phát triển. Các API tự động tạo quản lý toàn bộ danh mục khóa học của chúng tôi. Spring Boot chỉ được dùng cho các chứng chỉ PDF và email thông báo tiến độ. Kiến trúc đơn giản, dễ bảo trì và có khả năng mở rộng. Vui lòng cung cấp nội dung cần dịch.

Marketplace B2B (3k người dùng)

Vui lòng cung cấp nội dung cần dịch. Spring Boot quản lý các giao dịch giữa người mua và người bán (quan trọng). Supabase quản lý tất cả những phần còn lại: hồ sơ, nhắn tin thời gian thực, tài liệu. Việc cả hai cùng chia sẻ một cơ sở dữ liệu PostgreSQL giúp chúng tôi tránh được mọi quá trình đồng bộ hóa phức tạp. Lựa chọn kiến trúc tốt nhất mà chúng tôi từng thực hiện. Vui lòng cung cấp văn bản cần dịch.

Tổng hợp: Một Mô hình Kiến trúc Hiện đại

Kiến trúc hybrid Supabase + Spring Boot đại diện cho một mô hình mới:sự chuyên môn hóa về kiến trúcVì bạn chưa cung cấp nội dung cần dịch, vui lòng gửi văn bản tiếng Pháp mà bạn muốn chuyển sang tiếng Việt.

@startuml
skinparam backgroundColor #FEFEFE

rectangle "Mô hình cũ" #LightCoral {
  card "Mọi thứ ở Backend" {
    [Auth]
    [CRUD]
    [Logique Métier]
    [Jobs]
    [Storage]
    [Realtime]
  }
  note bottom
Độ phức tạp tối đa
ngay từ ngày 1
  end note
}

rectangle "Mô hình mới" #LightGreen {
  card "Supabase\n(Tiện ích)" {
    [Auth]
    [CRUD Simple]
    [Storage]
    [Realtime]
  }

  card "Spring Boot\n(Khác biệt hóa)" {
    [Logique Métier]
    [Jobs]
    [Intégrations]
  }

  note bottom
Độ phức tạp tăng dần
chỉ được thêm vào nếu cần thiết
  end note
}

[Ancien Paradigme] -right-> [Nouveau Paradigme] : Évolution

@enduml

Nguyên tắc cơ bản:Đừng xây dựng những gì đã tồn tại dưới dạng dịch vụ. Hãy tập trung vào những điểm tạo nên sự khác biệt cho ứng dụng của bạn.

Quy tắc 80/20

Trong hầu hết các ứng dụng:

  • 80% các hoạt độnglà các CRUD tiêu chuẩn → Supabase

  • 20% các hoạt độngyêu cầu logic nghiệp vụ → Spring Boot

Quy luật tự nhiên này lý giải cho kiến trúc hybrid.

@startuml
skinparam backgroundColor #FEFEFE

package "Phân phối các Hoạt động" {

  rectangle "80% - Hoạt động Tiêu chuẩn" #LightGreen {
    [Lecture de données]
    [Création d'entités]
    [Mise à jour simple]
    [Suppression]
    [Upload fichiers]
    [Authentification]

    note bottom: **Được quản lý bởi Supabase**
  }

  rectangle "20% - Logic Nghiệp vụ" #Coral {
    [Calculs complexes]
    [Workflows multi-étapes]
    [Transactions critiques]
    [Intégrations tierces]
    [Jobs planifiés]

    note bottom: Được quản lý bởi Spring Boot
  }
}

note right
**Tập trung tối ưu:**
Thời gian phát triển của bạn
tập trung vào 20% giá trị
tạo nên sự khác biệt cho sản phẩm của bạn
end note
@enduml

Kết luận cuối cùng

Kiến trúc hybrid không phải là một sự thỏa hiệp về kỹ thuật, mà là mộtquyết định chiến lượcVui lòng cung cấp văn bản tiếng Pháp cần dịch.

Nó cho phép bạn:

  • ✅ Bắt đầu nhanh chóng với một MVP hoạt động được

  • ✅ Xác thực thị trường của bạn mà không cần đầu tư lớn

  • ✅ Phát triển dần dần khi độ phức tạp yêu cầu

  • ✅ Kiểm soát chi phí của bạn ở mọi giai đoạn

  • ✅ Khai thác tối đa thế mạnh của mỗi công nghệ

  • ✅ Tránh việc thiết kế quá mức (over-engineering) sớm

  • ✅ Duy trì sự linh hoạt cho tương lai

Nó đại diện cho:

  • 🎯Chủ nghĩa thực dụng: Mỗi công nghệ mà cô ấy/nó xuất sắc

  • 🚀Vận tốc: Thời gian đưa ra thị trường tối thiểu

  • 💰Kinh tế: Chi phí căn chỉnh theo giá trị

  • 🔮Khả năng mở rộng: Kiến trúc phát triển cùng bạn

  • 🛡️Độ bền bỉ: Các dịch vụ đã được kiểm chứng và đáng tin cậy

Bước Tiếp Theo Của Bạn

Nếu kiến trúc này phù hợp với bạn, đây là nơi để bắt đầu:

  1. Tạo tài khoản Supabase(miễn phí)

  2. Hãy xác định lược đồ dữ liệu tối thiểu của bạn

  3. Cấu hình xác thực OAuth2

  4. Hãy tạo trang JBake đầu tiên của bạn có tiêu thụ API

  5. Triển khai trên GitHub Pages

Bạn sẽ có một MVP hoàn chỉnh trongvài ngàyVui lòng cung cấp văn bản cần dịch.

Spring Boot sẽ đến một cách tự nhiên khi bạn cần đến nó. Không sớm hơn.


Kiến trúc hybrid là nghệ thuật xây dựng chính xác những gì cần thiết, vào đúng thời điểm cần thiết.

Chúc bạn phát triển thuận lợi! 🚀


Hãy chia sẻ bài viết này nếu bạn nghĩ rằng nó có thể giúp các nhà phát triển khác đưa ra những lựa chọn kiến trúc đúng đắn.

Bài viết liên quan