Sorry cậu, tớ đã miss câu hỏi trước của cậu
Để tớ lần lượt trả lời 2 câu hỏi nhé!
Câu hỏi 1:
Anh có thể cho em xin ví dụ thực tế luôn được không?
Lấy ví dụ ở một trường đại học, cậu có một hệ thống quản lý sinh viên, với khả năng tra cứu thông tin sinh viên, điểm số qua các kỳ, v.v.
Một ngày nọ, trường đó muốn xây dựng hệ thống đăng ký sách ở @library. Tất nhiên, họ muốn có thông tin toàn bộ sinh viên trong trường, đặc biệt là địa chỉ nhà, để trong TH cần họ có thể gửi thư tới tận nhà để lấy sách.
Tuy vậy, hệ thống quản lý được thiết kế tương đối kém, nên không có cách nào dễ dàng để lấy được thông tin sinh viên thông qua API, cũng như việc xây dựng lại hệ thống thông tin sinh viên lại từ đâu cũng sẽ tốn kém nguồn lực. Việc tích hợp hệ thống book sách vào hệ thống thông tin sinh viên cũng không ổn, vì 2 vấn đề đó không liên quan lắm tới nhau, và không ai muốn việc book trả sách có thể khiến cho cả trường không đăng ký nổi môn học
Một kỹ sư thông minh nào đó đã đưa ra giải pháp đơn giản, đấy là dump database ở bên hệ thống thông tin sinh viên, lọc dữ liệu, và insert nó vào database ở bên hệ thống book sách. Mỗi năm, họ chỉ cần làm việc đó 1 lần, do đặc thù của trường đại học.
Cơ mà, trong TH một sinh viên nào đó chuyển địa chỉ nhà, và khai báo với nhà trường, hệ thống thông tin của trường sẽ có thông tin mới nhất, nhưng hệ thống book sách lại vẫn còn dữ liệu cũ, và chỉ có thể được update lại ở đầu năm học. Điều đó dẫn tới sự thiếu nhất quán về dữ liệu giữa 2 hệ thống.
Đó là ví dụ cho sự thiếu nhất quán dữ liệu giữa 2 hệ thống 2 hệ thống trên đều quan tâm tới model sinh viên, nhưng có khả năng trả về 2 kết quả khác nhau cho 1 sinh viên.
Câu hỏi 2:
Không biết có thể tạo transaction cho client khi connect với server qua REST API giống như cách mà web server tạo transaction với DBMS không ạ? Ví dụ client là web SPA hoặc mobile app thực hiện giao dịch là mua hàng, để tạo đơn cần phải gọi rất nhiều API phía server mới hoàn tất một giao dịch.
Cậu có thể implement transaction với nhiều micro service cùng tham gia, nhưng không phải Database level.
Với ví dụ của cậu, cậu sẽ có thể implement như thế này:
- Khi tạo order, ở Order service, sau khi tính toán và lấy đủ dữ liệu từ các service khác cậu có thể:
- Gọi tới Inventory service để trừ các item trong order.
- Gọi tới coupon service để đánh dấu coupon đã được sử dụng.
- Gọi tới Point service để thanh toán point
- Gọi tới Payment service để thanh toán tiền.
- Lưu dữ liệu vào database của order service và hoàn thành transaction.
- Nếu bất cứ lỗi gì xảy ra, cậu buộc phải tự implement cách rollback những thứ ở trên.
- Nếu cậu gặp lỗi khi gọi tới coupon, cậu phải gọi tới Inventory service để rollback lại bước trừ item trong inventory. Inventory service phải support hoạt động này.
- Tương tự với bất cứ lỗi nào xảy ra khi cậu gọi tới bất cứ service khác, cậu cần rollback lại những bước đã xảy ra. Các service đều phải support hoạt động đó.
Đó là cách cậu implement transaction khi làm việc với nhiều API/service.
Câu hỏi 3:
Theo cá nhân em nghĩ nếu để cho client call quá nhiều API cho một task nào đó thì lỗi do ông thiết kế backend sai đúng không ạ? Backend phải tối ưu enpoint làm sao để cho client chỉ cần tạo một HTTP request POST duy nhất là tạo được đơn hàng.
Cậu đúng về việc nên chỉ có 1 endpoint cho một việc nào đó, để front end/app gọi tới. Cơ mà, tớ không nghĩ có thể quy trách nhiệm đó ở backend
Backend thường sẽ expose cho cậu các endpoint để các app/client/front-end có thể tùy biến sử dụng. Thường các endpoint đó được thiết kế làm một việc cụ thể, và thường một business flow sẽ cần phải làm nhiều việc khác nhau.
Thường, việc tạo ra 1 endpoint duy nhất như cậu mong muốn sẽ thường được đặt ở các tầng aggregate service (tầng này tổng hợp dữ liệu từ nhiều service để đưa ra 1 model), hoặc được đặt ở BFF (Backend For Front-end). Owner của aggregate service có thể là của backend team (nếu các client đều sử dụng dữ liệu đó), và BFF thường thuộc về front-end (nơi họ có thể tự tùy biến các thao tác theo nghiệp vụ của họ).
Ngoài ra, gần như không thể optimize các endpoint sao cho chỉ có 1 endpoint cho một công việc Ngay ở ví dụ trên về việc tạo order, logic tớ kể trên là ví dụ cơ bản, trong thực tế, có rất nhiều payment method ở domain EC. Có payment method phải được thực hiện:
- Trước khi tạo order (credit card chẳng hạn, vì cậu sẽ buộc phải authorize payment transaction thông qua một hệ thống nào đó)
- Trong lúc tạo order (ví Momo, Paypal chẳng hạn).
- Sau khi tạo order (Cash On Delivery).
Điều này khiến cho việc có 1 endpoint duy nhất để phục vụ tất cả mọi business scenario gần như bất khả thi ở các domain phức tạp.
Hi vọng tớ đã trả lời được các thắc mắc của cậu.