명령에서 유효성 검사 후 오류를 처리하는 방법 (DDD + CQRS)


18

예를 들어 등록 양식을 제출할 때 Domain Model( WriteModelin CQRS)에 유효한 상태 (예 : 이메일 주소 구문, 연령 등) 가 있는지 확인해야합니다 .

그런 다음을 만들어로 Command보냅니다 Command Bus.

나는 명령이 아무것도 반환해서는 안된다는 것을 이해합니다.

그렇다면 오류를 Command Bus어떻게 처리 합니까? (예를 들어, 사용자가 1 초 전에 등록한 경우 username/email).

해당 명령이 실패한 것을 어떻게 알 수 있으며 오류를 어떻게 알 수 있습니까?


2
이벤트 버스가 필요하지 않습니다. CQRS를 구현할 때 모두가 이벤트 버스가 필요하다고 생각하는 이유는 무엇인지 모르겠습니다. CQRS는 단순히 쓰기와 읽기를 완전히 분리하고 별도의 문제를 해결한다는 의미입니다. 그렇게하는 한 CQRS가 있습니다. 명령은 비동기식 일 필요조차 없습니다. 오류보고 기능이있는 동기 명령이 효과가 있다면 그렇게하십시오.
Andy

1
명령이 성공하면 아무 것도 반환하지 않아야합니다 . 이 아이디어는 CQS 에서 시작되었으며 명령에서 여전히 오류에 대한 예외가 발생할 수 있습니다. 당신이 설명하는 것은 단방향 명령입니다. 이와 관련 하여이 답변 을 참조하십시오 .
Kasey Speakman

답변:


4

나는 명령이 아무것도 반환해서는 안된다는 것을 이해합니다.

그것은 하나의 견해이지만, 완전히 돌로 설정되지는 않았습니다. HTTP에서 쓰기 (PUT, POST, DELETE)를 고려하십시오. 이러한 모든 메시지는 자원 변경 상태를 요청하는 메시지이므로 응답을 리턴한다는 의미에서 명령입니다.

그렇다면 커맨드 버스 이외의 오류를 어떻게 처리합니까? (예를 들어, 동일한 사용자 이름 / 이메일로 1 초 전에 등록한 사용자).

해당 명령이 실패한 것을 어떻게 알 수 있으며 오류를 어떻게 알 수 있습니까?

따라서 명령 핸들러와 직접 통신하는 경우 리턴 된 메시지는 명령이 수신되어 처리되었음을 인식하는 데 매우 합리적인 방법입니다.

버스와 같이 대상과 직접 통신하지 못하게하는 미들웨어를 사용하는 경우 비동기 메시징 패턴을 살펴 보는 것이 좋습니다. 명령 처리기가 메시지를 다시 보내도록하는 방법은 무엇입니까? 방문객?

한 가지 아이디어는 명령의 결과를 구독하는 것입니다. 이것은 Hohpe의 엔터프라이즈 통합 패턴 (Enterprise Integration Patterns)의 아이디어 중 일부에서 나온 것입니다. 기본 아이디어는 클라이언트가 전송 된 명령 메시지에 익숙하기 때문에 명령 메시지의 결과로 게시 된 새 메시지를 구독 할 수있는 위치에 있다는 것입니다. 명령 처리기는 데이터를 레코드에 저장 한 후 변경이 성공했음을 알리는 이벤트를 게시하고 클라이언트는 해당 이벤트를 구독합니다. 메시지에서 다양한 식별자의 일치 성을 고려하여 올바른 이벤트를 인식합니다. 상관 관계 ID 등).

대체 접근 방식이 조금 더 직접적입니다. 하나는 메시지가 성공적으로 처리 된 후 명령 핸들러에 의해 호출 될 수있는 콜백을 메시지에 포함시키는 것입니다.

매우 유사한 대안은 명령 핸들러가 승인을 작성할 수 있도록 명령 메시지에 공간을 확보하는 것입니다. 클라이언트에 이미 명령 메시지가 있으므로 회로는 이미 완료되었습니다. " 약속 "또는 " 완성 가능한 미래" 라고 생각하십시오 . 메시지는 명령 핸들러에게 승인을 작성할 위치를 알려줍니다. 그렇게하면 승인이 가능하다는 것을 클라이언트 (카운트 다운 래치)에 알립니다.

물론 올바른 일을하는 데 방해가되는 것 같은 미들웨어를 제거하는 추가 옵션이 있습니다.

예를 들어, 동일한 사용자 이름 / 이메일로 1 초 전에 등록 된 사용자

사용자 등록을 dem 등적으로 처리하는 경우 반드시 오류 일 필요는 없습니다. 응답이 관찰 될 때까지 메시지를 반복하는 것이 적어도 한 번 전달되도록하는 일반적인 방법입니다.


2

예를 들어, 등록 양식을 제출할 때 도메인 모델 (CQRS의 WriteModel)에서 유효한 상태 (예 : 이메일 주소 구문, 연령 등)인지 확인해야합니다.

많은 유형의 유효성 검사가 있습니다. 전자 메일 주소 구문 및 보존 기간을 확인할 때의 유효성 검사는 Command가 수행 할 수있는 유효성 검사 유형입니다. 이것은 실제로 도메인 문제가 아닙니다. 일부 도메인 전문가가 해당 사양을 알려주기 때문에 명령 생성시 이러한 종류의 유효성 검사를 수행해야합니다. 실제로, 일반적인 아이디어는 명령이 작성되어 BUS로 전송 된 후에는 조치를 취하는 것이 더 복잡하기 때문에 가능한 빨리 검증을 수행하는 것입니다.

그렇다면 커맨드 버스 이외의 오류를 어떻게 처리합니까? (예를 들어, 동일한 사용자 이름 / 이메일로 1 초 전에 등록한 사용자).

이러한 종류의 검증은 CQRS 시작부터 CQRS 커뮤니티에서 많이 논의됩니다. 어디서 할까? 매우 논쟁의 여지가 있습니다. 개인적으로 다음과 같은 접근 방식을 사용합니다. 명령이 BUS로 전송되기 전에 사용자 이름 / 이메일을 중앙 집중식으로 취한 것으로 표시합니다 (예 : 사용자 이름 / 이메일의 고유 인덱스 제약 조건). 그 후 나는 명령을 보냅니다. 단점은 명령이 실패하면 짧은 시간 동안 사용자 이름이 사용되고 사용되지 않는다는 것입니다. 이것은 내 사업에 허용되며 귀하의 비즈니스에 적합합니다.

해당 명령이 실패한 것을 어떻게 알 수 있으며 오류를 어떻게 알 수 있습니까?

도메인 불변으로 인해 Aggregate가 비동기 명령을 거부하는 경우 명령 발행자에게 어떤 식 으로든 통보하는 보상 명령을 실행하여 몇 가지 조치를 취해야합니다 (즉, 명령이 실패했다는 설명 이메일을 보냅니다).

중복 이메일의 문제점은 해당 이메일 주소가 다른 사람의 것이기 때문에 이메일을 보낼 수 없다는 것입니다. 따라서 명령을 버스로 보내기 전에 확인해야합니다.


1

유효성 검사는 데코레이터에서 수행해야합니다. 그런 다음 유효성 검사가 필요한 모든 명령을 그대로 장식 할 수 있습니다.

명령으로 void를 반환하면 반환 된 작업 결과와 함께 동기화 또는 비동기 호출로 선택할 수있는 경우 유효성 검사를 예외로 처리 할 수 ​​있습니다.

또 다른 가능성은 유효성 검사를 유효성 검사 결과를 반환하는 "쿼리"유형으로 생각하는 것입니다. 유효성 검사 쿼리를 실행 한 다음 통과되면 명령을 실행하십시오. 이것은 데코레이터 접근법의 대안이 될 것입니다.


가장 깨끗한 방법이기 때문에 예외 접근 방식이 마음에 듭니다. 그러나 예외가 너무 무겁지 않습니까?
EresDev

1
안녕하세요 @EresDev-네, 무겁습니다. 그러나 데이터가 "유효한"지 모르겠습니다. 1000 개의 레코드 중 2 개가 유효하지 않다고 가정합니다. 예외적 인 조건이므로 예외가 발생할 수 있습니다. 이제 200이 유효하지 않은 1000 개의 레코드를 고려하십시오. 따라서 데이터의 20 %가 유효하지 않으므로 예외를 피해야합니다. 따라서 현재 데이터 유효성에 따라이 방법을 선택할지 여부를 결정해야합니다. :)
Jon Raynor 12'12

50 % 이상의 사용자가 유효하지 않은 데이터를 먼저 삽입한다고 생각하는 등록 양식의 예를 유지하면 예외는 괜찮습니다. 웹 응용 프로그램 백엔드는 프런트 엔드도 유효성 검사를 수행하기 때문에 대부분 유효한 데이터를 얻습니다. 뭔가가 드물게 프론트 엔드 유효성 검사를 놓친 경우 나 누군가가 장난하는 경우에만 얻을 수 있습니다. 따라서이 경우 예외는 매우 좋습니다.
EresDev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.