Cách xử lý lỗi sau xác thực trong lệnh (DDD + CQRS)


17

Ví dụ: khi bạn gửi biểu mẫu Đăng ký, bạn phải kiểm tra Domain Model( WriteModeltrong CQRS) rằng nó ở trạng thái hợp lệ (ví dụ: cú pháp địa chỉ email, tuổi, v.v.).

Sau đó, bạn tạo một Command, và gửi nó cho a Command Bus.

Tôi hiểu rằng các lệnh không nên trả lại bất cứ điều gì.

Vậy làm thế nào để bạn xử lý một lỗi ngoài Command Bus? (Ví dụ: người dùng đã đăng ký 1 giây trước đó với cùng username/email).

Làm thế nào để bạn biết lệnh đó thất bại, và làm thế nào để bạn biết lỗi?


2
Bạn không cần một chiếc xe buýt sự kiện. Tại sao mọi người nghĩ rằng bạn cần một chiếc xe buýt sự kiện khi thực hiện CQRS, tôi chỉ không biết. CQRS đơn giản có nghĩa là bạn hoàn toàn tách biệt viết và đọc, thực hiện các mối quan tâm riêng biệt. Bạn có CQRS miễn là bạn làm điều đó. Các lệnh của bạn thậm chí không cần phải không đồng bộ. Nếu các lệnh đồng bộ với báo cáo lỗi làm việc cho bạn, hãy làm điều đó.
Andy

1
Các lệnh không nên trả lại bất cứ điều gì khi thành công . Ý tưởng bắt đầu từ CQS , với hàm ý rằng lệnh vẫn có thể đưa ra một ngoại lệ do lỗi. Những gì bạn đang mô tả là một lệnh một chiều. Xem câu trả lời này liên quan đến điều đó.
Kasey speakman

Câu trả lời:


3

Tôi hiểu rằng các lệnh không nên trả lại bất cứ điều gì.

Đó là một góc nhìn, nhưng nó không hoàn toàn được đặt trong đá. Xem xét việc ghi (PUT, POST, DELETE) trong HTTP - tất cả các thông báo này là các lệnh, theo nghĩa là chúng là các thông báo yêu cầu trạng thái thay đổi tài nguyên và tất cả chúng đều trả về phản hồi.

Vậy làm thế nào để bạn xử lý một lỗi ngoài Command Bus? (Ví dụ: người dùng đã đăng ký 1 giây trước đó với cùng tên người dùng / email).

Làm thế nào để bạn biết lệnh đó thất bại, và làm thế nào để bạn biết lỗi?

Vì vậy, trong trường hợp bạn đang liên lạc trực tiếp với trình xử lý lệnh, một tin nhắn được trả về là một cách hoàn toàn hợp lý để xác nhận rằng lệnh đã được nhận và xử lý.

Nếu bạn đang sử dụng một phần mềm trung gian, như xe buýt, ngăn bạn liên lạc trực tiếp với mục tiêu, thì tôi khuyên bạn nên tìm đến các mẫu nhắn tin không đồng bộ - làm thế nào để bạn xử lý lệnh để gửi tin nhắn trở lại người gọi?

Một ý tưởng là đăng ký kết quả của lệnh; điều này mượn từ một số ý tưởng trong Mô hình tích hợp doanh nghiệp của Hohpe. Ý tưởng cơ bản là, vì máy khách đã quen thuộc với thông báo lệnh đã được gửi, nên nó có vị trí tốt để đăng ký bất kỳ tin nhắn mới nào được xuất bản do hậu quả của thông báo lệnh. Trình xử lý lệnh, sau khi lưu dữ liệu vào sổ ghi chép, xuất bản các sự kiện thông báo rằng thay đổi đã thành công và khách hàng đăng ký các sự kiện đó - nhận ra các sự kiện chính xác bằng cách xem xét sự trùng hợp của các số nhận dạng khác nhau trong thông báo (id nguyên nhân, id tương quan , vân vân).

Phương pháp thay thế là một chút trực tiếp hơn. Một là sẽ bao gồm trong tin nhắn một cuộc gọi lại, có thể được gọi bởi trình xử lý lệnh sau khi tin nhắn được xử lý thành công.

Một cách khác rất giống là dự trữ không gian trong thông báo lệnh để trình xử lý lệnh viết xác nhận - vì máy khách đã có thông báo lệnh trong câu hỏi, mạch đã hoàn tất. Hãy suy nghĩ " lời hứa " hoặc " tương lai hoàn thành". Thông báo cho người xử lý lệnh nơi viết xác nhận; làm như vậy báo hiệu cho khách hàng (chốt đếm ngược) rằng xác nhận có sẵn.

Và tất nhiên, bạn có tùy chọn bổ sung để loại bỏ phần mềm trung gian dường như đang cản trở việc thực hiện đúng cách một cách đơn giản.

Ví dụ: người dùng đã đăng ký 1 giây trước đó với cùng tên người dùng / email

Nếu bạn đang xử lý đăng ký người dùng một cách bình thường, đó không nhất thiết là lỗi - lặp lại tin nhắn cho đến khi nhận được phản hồi là cách phổ biến để đảm bảo ít nhất một lần giao hàng.


1

Ví dụ: khi bạn gửi biểu mẫu Đăng ký, bạn phải kiểm tra Mô hình miền (WriteModel trong CQRS) rằng nó ở trạng thái hợp lệ (ví dụ: cú pháp địa chỉ email, tuổi, v.v.)

Có nhiều loại xác nhận. Xác thực khi bạn kiểm tra cú pháp địa chỉ email và định dạng tuổi là một loại xác thực mà Lệnh có thể thực hiện. Đây không thực sự là một mối quan tâm tên miền. Có vẻ như vậy bởi vì một số chuyên gia tên miền sẽ cho bạn biết các thông số kỹ thuật đó nhưng bạn nên thực hiện loại xác thực này trong quá trình tạo Lệnh. Trong thực tế, ý tưởng chung là thực hiện xác nhận càng sớm càng tốt bởi vì sau khi một lệnh được tạo và gửi tới một xe buýt, việc thực hiện các hành động sẽ phức tạp hơn.

Vậy làm thế nào để bạn xử lý một lỗi ngoài Command Bus? (Ví dụ: người dùng đã đăng ký 1 giây trước đó với cùng tên người dùng / email).

Kiểu xác nhận này được thảo luận rất nhiều trong cộng đồng CQRS, từ khi bắt đầu CQRS. Làm ở đâu? Nó là rất tranh luận. Cá nhân tôi sử dụng cách tiếp cận sau: Trước khi lệnh được gửi tới BUS, tôi đánh dấu tên người dùng / email theo cách tập trung (nghĩa là một ràng buộc chỉ mục duy nhất trên tên người dùng / email). Sau đó tôi gửi lệnh. Hạn chế là, nếu lệnh thất bại, trong một khoảng thời gian ngắn tên người dùng được sử dụng và không được sử dụng; điều này được chấp nhận cho doanh nghiệp của tôi, có thể xảy ra cho doanh nghiệp của bạn.

Làm thế nào để bạn biết lệnh đó thất bại, và làm thế nào để bạn biết lỗi?

Nếu một lệnh không đồng bộ bị từ chối bởi Tập hợp vì bất biến miền thì một số biện pháp phải được thực hiện bằng cách ban hành một số lệnh bù mà bằng cách nào đó thông báo cho người phát hành lệnh (tức là gửi email giải thích rằng lệnh không thành công).

Vấn đề với email trùng lặp là bạn không thể gửi email vì địa chỉ email đó thuộc về người khác, đó là lý do tại sao tôi kiểm tra nó trước khi gửi lệnh tới xe buýt.


1

Xác nhận nên được thực hiện trong một trang trí. Sau đó, bất kỳ lệnh nào cần xác nhận có thể được trang trí như vậy.

Xác thực có thể được xử lý với các trường hợp ngoại lệ nếu bạn trả về khoảng trống bằng lệnh của bạn để chúng có thể được chọn với các cuộc gọi đồng bộ hóa hoặc không đồng bộ với kết quả tác vụ được trả về.

Một khả năng khác là nghĩ về xác nhận là một loại "truy vấn" sẽ trả về kết quả xác thực. Chạy truy vấn xác nhận, và sau đó nếu được thông qua, hãy chạy lệnh. Đây sẽ là một thay thế cho phương pháp trang trí.


Tôi thích cách tiếp cận ngoại lệ vì đó là cách sạch nhất. Nhưng không ngoại lệ quá nặng cho việc này?
EresDev

1
HI @EresDev - Vâng, họ rất nặng. Nhưng, tôi không biết dữ liệu của bạn "hợp lệ" như thế nào. Cho phép trong số 1000 hồ sơ 2 không hợp lệ. Các ngoại lệ có thể khả thi vì chúng thực sự là điều kiện đặc biệt. Bây giờ hãy xem xét 1000 hồ sơ với 200 không hợp lệ. Trong nguyên nhân đó, nên tránh các ngoại lệ vì 20% dữ liệu của bạn không hợp lệ. Vì vậy, tôi để bạn quyết định xem có nên chọn phương pháp này hay không dựa trên tính hợp lệ của dữ liệu hiện tại của bạn. :)
Jon Raynor

Tôi sẽ thêm vào điều này bằng cách nói rằng nếu chúng ta giữ ví dụ về mẫu đăng ký, nơi tôi nghĩ 50% hoặc thậm chí nhiều người dùng chèn dữ liệu không hợp lệ trước, ngoại lệ vẫn ổn. Trong phụ trợ ứng dụng web, bạn chủ yếu nhận được dữ liệu hợp lệ vì các giao diện cũng đang thực hiện xác nhận. Bạn chỉ nhận được nếu một cái gì đó đã bỏ lỡ xác nhận frontend bởi một số cơ hội hiếm có hoặc nếu ai đó đang lừa xung quanh. Vì vậy, các trường hợp ngoại lệ là rất nhiều ổn trong trường hợp này.
EresDev
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.