Vẽ trách nhiệm phía sau một tính năng full stack
Phân chia trách nhiệm của tính năng xuất báo cáo, từ giao diện đến lưu trữ, rồi kiểm tra trường hợp thu hồi quyền và công việc bị kẹt.

Một tính năng full stack dễ thảo luận hơn khi bạn vẽ ra các quyết định mà từng phần chịu trách nhiệm. Tôi thích làm việc đó trước khi chia đầu việc hoặc chọn dịch vụ. Sơ đồ thành phần cho biết mã chạy ở đâu; bản đồ trách nhiệm còn cho biết ai định nghĩa hành vi khi yêu cầu thất bại, phải chờ hoặc đi qua ranh giới bảo mật.
Xét tính năng xuất báo cáo giả định. Người dùng yêu cầu báo cáo, chờ một tiến trình nền tạo tệp rồi tải kết quả về. Trong dự án học tập, giao diện, API, tiến trình nền và nơi lưu trữ có thể do một người làm hết. Chúng vẫn có trách nhiệm khác nhau. Bỏ sót một trách nhiệm có thể tạo ra tính năng trông đã hoàn thành nhưng chưa rõ cách khôi phục khi gặp lỗi.
Bắt đầu từ điều hứa với người dùng
Viết một câu về điều sản phẩm cung cấp: “Yêu cầu báo cáo cho những bản ghi bạn có quyền truy cập, rồi tải tệp đã hoàn thành khi sẵn sàng.” Câu đó chứa nhiều quyết định chưa được nói rõ.
Người dùng được truy cập những bản ghi nào? Việc xuất dùng quyền tại thời điểm yêu cầu hay lúc tải? Tệp được giữ bao lâu? Điều gì xảy ra nếu tiến trình nền đã tạo tệp nhưng dừng trước khi ghi nhận hoàn thành? Người dùng phân biệt một yêu cầu đang xếp hàng với yêu cầu đã bị mất như thế nào?
Bạn chưa cần trả lời hết ngay. Đặt mỗi câu hỏi cạnh phần hệ thống có thể thực thi câu trả lời. Quyết định sản phẩm về thời hạn lưu phải xuất hiện trong hợp đồng hành vi, còn cấu hình lưu trữ và mã dọn dẹp phải thực hiện nó. Nếu không ai chịu trách nhiệm nối hai phía, cuộc trao đổi về “việc lưu tệp” có thể bỏ qua yêu cầu thực sự.
Ghép quyết định với bằng chứng
Bản đầu tiên có thể nối quyết định với bằng chứng như sau:
| Ranh giới | Quyết định chịu trách nhiệm | Bằng chứng cần xem |
|---|---|---|
| Giao diện | Cách giải thích trạng thái chờ, lỗi và hoàn thành | Các bước hiển thị từng trạng thái và hành động xử lý tiếp dùng được |
| API | Ai được yêu cầu báo cáo nào và nhận mã gì | Trường hợp được phép và không được phép |
| Tiến trình nền | Cách công việc đổi trạng thái và xử lý lần thử khác | Chuỗi trạng thái có cả lần thực hiện bị gián đoạn |
| Lưu trữ | Ai được tải tệp và khi nào tệp hết hạn | Kiểm tra truy cập và quy tắc lưu giữ rõ ràng |
| Vận hành | Cách phát hiện công việc bị kẹt và ai xử lý | Tín hiệu, người phụ trách và quy trình điều tra đã kiểm tra |
Kiến trúc khác có thể đặt một số trách nhiệm ở chỗ khác. Mối liên hệ cần giữ là giữa quyết định và bằng chứng cho thấy cách triển khai tuân theo quy tắc dự định.
Nhánh vận hành bổ sung rất quan trọng. Công việc có thể ở trạng thái chờ mãi mà không phát sinh ngoại lệ rõ ràng. Nếu giao diện cứ hỏi lại trạng thái, người dùng có thể chờ vô hạn trong khi từng thành phần đều có vẻ vẫn chạy.
Tìm các điểm bàn giao cần thống nhất hành vi
Giả sử API trả về mã công việc trước khi tiến trình nền bắt đầu. Giao diện cần biết sẽ nhận những trạng thái nào khi hỏi mã đó. Tiến trình nền cần biết thử lại có được tạo thêm tệp khác hay không. Nơi lưu trữ cần quy tắc cho những đối tượng còn lại sau lần thực hiện bị gián đoạn.
Viết thỏa thuận bằng hành vi quan sát được. “Tiến trình nền phải đáng tin cậy” quá rộng. “Một lần thử lại cho công việc đã hoàn thành không được công bố hai kết quả tải khác nhau” là điều kiện mọi người có thể kiểm tra, dù cách triển khai vẫn cần được thiết kế.
Hướng dẫn review kỹ thuật của Google hỏi thiết kế của thay đổi có phù hợp với hệ thống và chức năng có đúng nhu cầu hay không. Bản đồ trách nhiệm giúp người review tìm hành vi xung quanh mà một bản sửa cục bộ có thể ảnh hưởng. Đổi tên trạng thái của tiến trình nền cũng thay đổi cách giao diện diễn giải, trừ khi có lớp chuyển đổi giữ nguyên hợp đồng.
Giao rõ người phụ trách phần còn thiếu
Bản đồ chỉ hữu ích nếu dẫn tới một hành động. Đánh dấu quyết định chưa thống nhất một cách cụ thể, thay vì đặt vào ô “để sau”. Chẳng hạn, bản phát hành đầu chưa thống nhất thời hạn lưu tệp. Đây là câu hỏi về sản phẩm và vận hành cần giải quyết trước khi các tệp vô tình được giữ mãi.
Trong nhóm, phân biệt người triển khai thay đổi với người có thẩm quyền quyết định chính sách. Lập trình viên có thể viết mã xóa, còn bên sản phẩm hoặc pháp lý đưa ra yêu cầu lưu giữ. Với dự án cá nhân để học, bạn có thể tự quyết định nhưng vẫn nên ghi giả định đó.
Chương Google SRE về mục tiêu mức dịch vụ giải thích vai trò của chỉ số và mục tiêu trong việc mô tả hành vi dịch vụ. Ở ví dụ này, chỉ số hữu ích có thể là số báo cáo hoàn thành trong thời gian đã thống nhất. Chỉ đo tiến trình có đang chạy không sẽ chưa trả lời được người dùng có nhận tệp hay không.
Giữ bản đồ vừa đủ cho tính năng
Cách làm này có thể trở nên rườm rà nếu mỗi hàm hỗ trợ đều có một ô trách nhiệm riêng. Vẽ ranh giới tại nơi lời hứa thay đổi, quyền truy cập thay đổi hoặc lỗi cần cách phản ứng khác. Với bản thử cục bộ, một trang và vài chuỗi trạng thái có thể đã đủ.
Trước khi triển khai, nhờ người khác theo một yêu cầu qua bản đồ và chỉ ra ai phụ trách khi báo cáo bị kẹt. Nếu họ phải đoán, sửa phần đó. Sau khi triển khai, so sánh chuỗi yêu cầu và công việc thực tế với bản vẽ. Bản đồ có giá trị khi giúp tìm hành vi còn thiếu hoặc làm cho điểm bàn giao dễ review hơn.
Thử bản đồ với quyền truy cập thay đổi giữa chừng
Bản đồ trách nhiệm hữu ích hơn khi bạn đưa một chuỗi sự kiện khó qua nó. Giả sử người dùng yêu cầu xuất khi còn là thành viên của một không gian làm việc. Công việc vẫn đang xếp hàng. Trước khi tiến trình nền bắt đầu, người dùng bị thu hồi tư cách thành viên. Tiến trình sau đó tạo ra tệp. Ai quyết định người dùng có được tải không?
Với sản phẩm giả định này, chọn một chính sách rõ ràng: người đã bị thu hồi quyền không còn được tải báo cáo của không gian đó. Lựa chọn này chưa tự quyết định tiến trình nền phải hủy, hoàn thành cho người khác còn quyền hay xóa kết quả. Đó là các quyết định bổ sung cần người phụ trách.
| Thời điểm | Quyết định cần đưa ra | Ranh giới có thể thực thi |
|---|---|---|
| Chấp nhận yêu cầu | Người dùng có được yêu cầu báo cáo này không? | Kiểm tra quyền tại API |
| Xóa tư cách thành viên | Quyền nào chấm dứt và từ lúc nào? | Chính sách sản phẩm và mô hình thành viên |
| Tiến trình nền bắt đầu | Công việc đang chờ còn cần thiết và được phép không? | Hợp đồng công việc và hành vi tiến trình |
| Yêu cầu tải | Người gọi hiện có được lấy kết quả không? | Kiểm tra quyền truy xuất |
| Giữ kết quả | Ai được truy cập đối tượng và trong bao lâu? | Cách triển khai quyền lưu trữ và thời hạn lưu |
Hướng dẫn kiểm tra quyền truy cập của OWASP đề nghị kiểm tra quyền trên các yêu cầu. Trong chuỗi này, kiểm tra ở yêu cầu ban đầu chưa đủ thực hiện chính sách tải đã chọn. Phải xem xét cả đường lấy kết quả.
Hình tách quyết định chính sách khỏi mã thực thi. Lập trình viên có thể triển khai một quy tắc rõ ràng, nhưng không nên âm thầm quyết định ngữ nghĩa truy cập của sản phẩm chỉ vì thư viện lưu trữ khiến một cách làm thuận tiện hơn.
Phân biệt người quyết định với người triển khai
Người viết tiến trình nền có thể không có thẩm quyền quyết định báo cáo chứa dữ liệu nhạy cảm được giữ bao lâu. Người định nghĩa thời hạn lưu có thể chưa biết cơ chế dọn dẹp nào thực hiện được yêu cầu một cách đáng tin cậy. Cần cả hai đóng góp, và bản đồ nên thể hiện mối nối đó.
Trong nhóm nhỏ, một người có thể giữ nhiều trách nhiệm. Vẫn nên viết tách chúng ra. Khi review, mọi người có thể hỏi chính sách đã thực sự được chọn chưa và mã có tuân theo nó không. Trong dự án cá nhân, bạn tự quyết định được, nhưng quy tắc thành văn vẫn tránh để tính năng sau dựa vào giả định khác.
Một lần bàn giao hữu ích có quy tắc, ví dụ liên quan và trường hợp biên còn chưa giải quyết. Với người bị thu hồi quyền, lập trình viên backend cần biết một quyền tải đã cấp trước đó có thể tiếp tục tồn tại sau khi mất tư cách thành viên hay không, và điều đó ảnh hưởng thế nào đến chính sách. Câu trả lời phụ thuộc cơ chế truy cập, không thể suy ra từ tên endpoint.
Tính cả kết quả còn lại sau lần thực hiện lỗi
Bây giờ xét tiến trình nền đã ghi tệp nhưng dừng trước khi đánh dấu công việc hoàn thành. Giao diện vẫn báo chờ, còn nơi lưu trữ đã có đối tượng. Thành phần nào nhận diện được đối tượng đó, quyết định có thể dùng lại không và xóa nếu cần?
Liên kết đối tượng với một mã công việc ổn định hoặc quan hệ khác có thể kiểm tra. Thiếu quan hệ đó, tiến trình dọn dẹp có thể không phân biệt được tệp bị bỏ lại với kết quả vẫn được sử dụng. Quy tắc lưu giữ cũng cần một mốc bắt đầu: lúc tạo, lúc công việc hoàn thành hay lần truy cập hợp lệ cuối sẽ dẫn tới thời điểm xóa khác nhau.
Bản đầu có thể chọn quy tắc đơn giản, như xóa đối tượng tạm không còn được tham chiếu sau một khoảng thời gian giới hạn trong môi trường thực hành. Nó vẫn phải nhận diện được các đối tượng đó và tránh xóa kết quả đã được chấp nhận. Ghi giả định và kiểm tra lần thực hiện bị lỗi riêng với lần xuất hoàn thành bình thường.
Để quá trình review đi theo lỗi qua nhiều bên phụ trách
Nhờ người review bắt đầu từ “người dùng không tải được báo cáo” và lần theo bằng chứng đang có. Họ có nhận diện được công việc, các lần thử và đối tượng kết quả không? Có biết người dùng hiện còn quyền không? Có bên phụ trách rõ ràng cho công việc chờ mà không có tiến trình nào thực hiện không?
Nếu điều tra dừng ở ranh giới nhóm, thêm điểm bàn giao hoặc khả năng quan sát còn thiếu. Điều đó chưa chắc cần dịch vụ hay bảng điều khiển mới. Một mã ổn định, sự kiện được ghi chính xác và người phụ trách đã thống nhất có thể đủ. Bản đồ trách nhiệm nên giúp giải quyết yêu cầu khó, thay vì tạo thêm một sơ đồ tổ chức không ai dùng lúc xảy ra lỗi.