Back to blog

Web Development Không Chỉ Là Frontend và Backend

web-developmentcareeropinionsoftware-engineering
Web Development Không Chỉ Là Frontend và Backend

Hầu hết developer đều bắt đầu với cùng một mô hình tư duy: frontend xử lý những gì người dùng thấy, backend quản lý logic phía server. Đây là một khung sườn hữu ích khi bạn mới học. Nhưng đến một lúc nào đó, cái tư duy nhị phân đó bắt đầu cản trở bạn.

Những thứ thực sự khiến ứng dụng thất bại — hay cảm thấy chưa hoàn chỉnh — hiếm khi nằm trong sự phân chia đơn giản đó. Chúng nằm ở những lớp vô hình ở giữa.


Cái Bẫy "Nó Chạy Được Rồi"

Có một giai đoạn cụ thể mà nhiều developer trải qua, khi code về mặt kỹ thuật là đúng nhưng sản phẩm lại cảm thấy chưa hoàn chỉnh. Các nút bấm phản hồi. API trả dữ liệu. Test pass hết.

Vậy mà vẫn thiếu gì đó.

Khoảng cách đó thật khó chịu vì khó đặt tên hơn là một bug. Nó không throw error. Nó chỉ nằm đó, khiến ứng dụng cảm giác như một bản nháp thô.

Thứ còn thiếu thường là một tập hợp các quyết định có chủ đích mà không có framework nào đưa ra thay cho bạn: chuyện gì xảy ra khi request bị chậm? Người dùng thấy gì khi có lỗi? Empty state của danh sách truyền đạt điều gì? Chuyện gì xảy ra khi ai đó điều hướng chỉ bằng bàn phím?

Ship thứ gì đó hoạt động chỉ là một nửa công việc. Nửa còn lại là thiết kế cách hệ thống hành xử.


Những Lớp Vô Hình

Những chi tiết định nghĩa một ứng dụng tốt, thân thiện với người dùng là những thứ người dùng hiếm khi nhận ra — cho đến khi chúng bị thiếu.

  • Loading state hiển thị progress thay vì im lặng
  • Thông báo lỗi giải thích điều gì đã sai và phải làm gì tiếp theo, không phải chỉ "Đã xảy ra lỗi"
  • Keyboard navigation hoạt động xuyên suốt toàn bộ giao diện
  • Độ tương phản màu sắc không loại trừ người dùng có khiếm khuyết thị giác
  • Empty state hướng dẫn thay vì gây nhầm lẫn
  • URL có thể đọc được mang tính dự đoán và có thể chia sẻ
  • Default hợp lý không cần cấu hình (thiết lập mặc định) vẫn hữu ích

Không có thứ nào trong những điều này đến từ việc chọn đúng framework. Chúng đến từ việc chúng ta có chủ động quan tâm đến hay không.

Và những lựa chọn này tích lũy theo thời gian. Một ứng dụng xử lý loading state tốt nhưng bỏ rơi người dùng khi có lỗi vẫn là trải nghiệm tệ. Các lớp vô hình hoạt động cùng nhau hoặc thất bại cùng nhau.


Backend Không Chỉ Là Endpoint

Ở phía server, nguyên tắc tương tự cũng áp dụng. Viết một API endpoint là phần dễ. Những gì bao quanh nó mới quyết định liệu hệ thống có thực sự đáng tin cậy hay không.

Hãy xem xét sự khác biệt giữa hai cách tiếp cận xử lý lỗi này:

// Phiên bản "nó chạy được"
try {
  const result = await doSomething()
  return res.json(result)
} catch (err) {
  return res.status(500).json({ message: 'Something went wrong' })
}
// Phiên bản có chủ đích
try {
  const result = await doSomething()
  return res.json(result)
} catch (err) {
  logger.error({ err, userId: req.user?.id, endpoint: req.path }, 'Operation failed')
 
  if (err instanceof ValidationError) {
    return res.status(400).json({
      message: 'Invalid input',
      fields: err.fields,
    })
  }
 
  return res.status(500).json({
    message: 'An unexpected error occurred. Please try again.',
    requestId: req.id,
  })
}

Phiên bản thứ hai không chỉ fail một cách graceful — nó cho người dùng thứ gì đó có thể hành động, cho developer thứ gì đó có thể debug, và coi độ tin cậy là một mối quan tâm hàng đầu.

Tư duy tương tự áp dụng cho việc validation đầu vào, logging, cấu hình môi trường, và các default an toàn. Đây không phải là polish tùy chọn. Đây là thứ phân biệt một script với một hệ thống.


Những Câu Hỏi Thúc Đẩy Sự Phát Triển

Sự thay đổi đẩy nhanh sự phát triển trong sự nghiệp xảy ra khi bạn thay đổi câu hỏi bạn đặt ra về công việc của chính mình.

Thay vì: "Thứ này có hoạt động không?"

Hãy bắt đầu hỏi:

  • Điều này có dễ hiểu đối với người dùng không có bối cảnh nào không?
  • Điều này có accessible đối với người dùng màn hình đọc hoặc chỉ dùng bàn phím không?
  • Điều này có maintainable cho developer sẽ đụng vào codebase này sau sáu tháng không?
  • Điều này có predictable — nó có hành xử theo cách người dùng mong đợi không?
  • Điều này có tử tế không — với người dùng khi có sự cố, và với đồng nghiệp kế thừa code này?

Những câu hỏi này không thuộc về frontend hay backend. Chúng áp dụng ở khắp mọi nơi: quyết định UI, thiết kế API, xử lý lỗi, deployment pipeline, database schema. Systems thinking không quan tâm bạn đang làm việc ở layer nào.


Zoom Out Là Cách Bạn Lên Level

Có một sự thật phản trực giác về sự phát triển trong phần mềm: cách nhanh nhất để giỏi hơn phần bạn đang làm là zoom out và hiểu tổng thể.

Nếu bạn chỉ nhìn component của mình trong sự cô lập, bạn không hiểu tại sao nó cần hành xử theo cách đó. Nếu bạn chỉ nhìn API endpoint, bạn không hiểu nó đang phục vụ trải nghiệm nào. Các ràng buộc, sự đánh đổi, và lý do đằng sau các quyết định chỉ trở nên rõ ràng khi bạn nhìn vào toàn bộ hệ thống.

Điều này không có nghĩa là bạn phải master mọi thứ. Nó có nghĩa là bạn phải chú ý nhiều hơn.

  • Tại sao API response này có field này mà dường như không ai dùng?
  • Tại sao component này fetch dữ liệu thay vì nhận nó qua props?
  • Tại sao thông báo lỗi này nói điều nó nói?
  • Ai đã viết cái này, và họ đang giải quyết vấn đề gì?

Chú ý những câu hỏi đó — và thỉnh thoảng tìm câu trả lời — xây dựng một loại bản đồ khiến mọi thứ khác nhanh hơn.


Điều Này Thực Sự Trông Như Thế Nào

Trên thực tế, việc quan tâm đến các lớp giữa frontend và backend trông như thế này:

Trong UI: Dành thêm một giờ cho error và loading state trước khi coi một tính năng là hoàn chỉnh. Kiểm tra keyboard navigation trước khi ship. Đọc giao diện của bạn như một người dùng lần đầu bị nhầm lẫn.

Trong API: Viết error response hữu ích, không chỉ là non-500. Thêm structured logging bắt được context. Validate đầu vào sớm với thông báo giải thích điều gì sai.

Xuyên suốt hệ thống: Hỏi tại sao thứ gì đó được thiết kế theo cách đó trước khi thay đổi nó. Cân nhắc trải nghiệm người dùng khi đưa ra quyết định kiến trúc backend. Cân nhắc các ràng buộc backend khi đưa ra quyết định UI.

Không có gì trong số này là anh hùng. Đó chỉ là thực hành quan tâm sâu hơn một lớp so với mức thực sự cần thiết.


Sự phân chia frontend/backend là một bản đồ hữu ích cho người mới học. Nhưng lãnh thổ thực tế phong phú hơn bản đồ.

Sự khác biệt giữa code hoạt động và phần mềm thực sự tốt nằm ở những lớp vô hình đó — những lựa chọn có chủ đích mà không có framework nào đưa ra cho bạn, những câu hỏi bạn hỏi trước khi ship, và sự sẵn sàng quan tâm đến những gì xảy ra sau khi happy path kết thúc.

Đó mới là web development thực sự là gì.

📬 Đăng ký nhận bản tin

Nhận những bài viết mới nhất qua email mỗi tuần. Không spam, hủy đăng ký bất cứ lúc nào.

Chúng tôi tôn trọng quyền riêng tư của bạn. Hủy đăng ký bất cứ lúc nào.

💬 Comments

Đăng nhập để bình luận

Chúng tôi sẽ không đăng bất cứ điều gì mà không có sự cho phép của bạn.