← Node / Backend Course

NODE / BACKEND CORE · 106

Backend Architecture:Route、Service、Repository、Transaction、Observability

Backend 變大後,真正問題不是「資料夾怎麼命名」,而是 responsibility boundary。你要能從一個 HTTP request 一路追到 business rule、database transaction,再回到 response。

Learning outcomes

1. 一條可追蹤的 request flow

HTTP Route
   ↓ parse / validate
Authenticated User
   ↓ authorize
Service
   ↓ business rule
Repository
   ↓ SQL / DB client
Database
   ↑ result
Service
   ↑ response model
HTTP Response

2. Route/controller:協調 HTTP,不要塞所有 business rule

async function createCourse(
  req,
  res
) {
  const input =
    parseCourseBody(
      req.body
    );

  if (!input.ok) {
    return res
      .status(400)
      .json(input);
  }

  const course =
    await courseService
      .create({
        user: req.user,
        input: input.data
      });

  res
    .status(201)
    .json(course);
}

3. Service:business operation

async function create({
  user,
  input
}) {
  if (
    await repository
      .existsByTitle(
        user.id,
        input.title
      )
  ) {
    throw new ConflictError();
  }

  return repository.insert({
    ownerId: user.id,
    title: input.title
  });
}

Service 不應依賴 Express req/res 才能運作,這讓 business rule 更容易測。

4. Repository:隔離 persistence details

async function insert(
  course
) {
  return db.query(
    "INSERT ...",
    [...]
  );
}

Repository 不是「一定要有的宗教規則」,但當 DB details 開始污染 business logic 時,這個 boundary 會有價值。

5. Transaction:一個 operation 要嘛全成,要嘛全失敗

BEGIN

insert course
insert audit record
update quota

COMMIT

若三個步驟共同代表一個 business operation,不能接受只完成前兩個。這時 transaction boundary 應包住整個一致性需求。

6. External API:更多 failure modes

風險問題
Timeout對方一直不回,要等多久?
Retry重送會不會重複扣款/寄信?
Idempotency同一 operation 重複送是否安全?
Rate limit429 怎麼處理?
Partial failureDB 成功但 email 失敗怎麼辦?

7. Observability:production bug 要有 evidence

{
  requestId,
  route,
  userId,
  durationMs,
  dbDurationMs,
  status,
  errorCode
}

不要只記「something failed」。至少要能串 request id、步驟、時間與 error category。

Project checkpoint:Course API final architecture

React Browser
   ↓ HTTPS
Express route
   ↓
request id
validation
authentication
authorization
   ↓
CourseService
   ↓
CourseRepository
   ↓ transaction
Postgres / Supabase
   ↑
response DTO
   ↑
JSON + status
   ↑
Browser

8. 101–106 最後真正學到什麼?

課核心能力
101runtime/process/config
102module/filesystem/path boundary
103TCP listener + raw HTTP request
104routing + middleware pipeline
105trust boundary + auth/error
106service/db/transaction/observability

Knowledge check / Final challenge

  1. 畫出 POST /courses 從 Browser 到 DB 的完整路徑。
  2. 每一層標出 input/output 與 failure evidence。
  3. 指出哪些規則應在 server,哪些可留 UI。
  4. 設計 request id 如何一路進 log / DB / external API。